Jono
Jono

Reputation: 199

AJAX file upload giving undefined file error

let me first explain what I aim to do, then display my code.

What I want to do is make a page which basically updates a user's details in the database, I did this part first and everything works perfectly here, through AJAX. Next I wanted to update the profile picture of the user as well through AJAX, so I made a normal file upload PHP page to make sure that my PHP code was working correctly and it was. Now I just needed to perform the upload via AJAX, and this is where I get stuck. I keep getting an error message from the PHP page which states undefined index: file.

Please feel free to ask any questions, and thank you for the responses.

Here is my HTML form:

<form action="upload.php?upload&type=profile" method="post" enctype="multipart/form-data">
    <label for="profile">Profile Picture</label><br />
    <img id="preview" width="200" height="200" src="<?php echo $user->getProfile(); ?>" alt="Profile Picture Preview" /><br />
    <br />
    <input type="file" name="file" id="file" onchange="loadImage(this);" /><br />
    <label for="username">Username</label><br />
    <input type="text" name="username" id="username" value="<?php echo $user->getUsername(); ?>" /><br />
    <label for="email">Email Adress</label><br />
    <input type="text" name="email" id="email" value="<?php echo $user->getEmail(); ?>" /><br />
    <label for="bio">Biography</label><br />
    <textarea name="bio" id="bio" cols="40" rows="5"><?php echo $user->getBio(); ?></textarea><br />
    <label for="password">New Password</label><br />
    <input type="password" name="password" id="password" /><br />
    <label for="oldPass">Current Password</label><br />
    <input type="password" name="oldPass" id="oldPass" /><br />
    <label for="first">First Name</label><br />
    <input type="text" name="first" id="first" value="<?php echo $user->getFirstName(); ?>" /><br />
    <label for="last">Last Name</label><br />
    <input type="text" name="last" id="last" value="<?php echo $user->getLastName(); ?>" /><br />
    <br />
    <input type="submit" name="update" value="Save" id="update" />&nbsp;<input type="button" name="reset" value="Reset Fields" onclick="resetFields()" />
</form>

Here is my js file containing the AJAX:

$(document).ready(function() {
    $("#update").click(function() {
        profile = "pictures/default.jpg";
        username = $("#username").val();
        email = $("#email").val();
        bio = $("#bio").val();
        newPass = $("#password").val();
        oldPass = $("#oldPass").val();
        first = $("#first").val();
        last = $("#last").val();

        // First an ajax request to upload the image as it requires separate request
        $.ajax({
            type: "POST",
            url: "upload.php?upload&type=profile",
            data: new FormData(this),
            contentType: false,
            cache: false,
            processData: false,
            success: function(resp) {
                alert(resp);
            },
            error: function (resp) {
                alert(resp);
            }
        });

        // Now the updates in the profile
        $.ajax({
            type: "POST",
            url: "update.php",
            data: "mode=details&profile="+profile+"+&username="+username+"&email="+email+"&bio="+bio+"&password="+newPass+"&oldPass="+oldPass+"&first="+first+"&last="+last,
            success: function(resp) {
                // resp contains what is echoed on update.php
                alert(resp);
            }
        });
        return false;
    });
});

Finally, here is my PHP Code:

include "base.php";
// Kick user off this page if they are not logged in
if (!isset($user)) {
    echo "<meta http-equiv='refresh' content='0.1;url=index.php'>";
    exit();
}
if (isset($_GET['upload'])) {
    switch ($_GET['type']) {
        case "profile": {
            $dir = "pictures/";
            $maxFileSize = 2000000; // 2mb
            $extensions = array("jpg", "jpeg", "png", "gif");
            $currentPath = pathinfo($_FILES['file']['name']);
            $fileType = $currentPath['extension'];
            $targetFile = $dir.$user->getUsername()."Profile.".$fileType;
        }
        break;
        default: {
            echo "<meta http-equiv='refresh' content='0.1;url=index.php'>";
            exit();
        }
        break;
    }

    $upload = true;

    // Check the file size
    if ($_FILES['file']['size'] > $maxFileSize) {
        echo "The file is too large.";
        $upload = false;
    }

    // Limit file types
    if (!in_array($fileType, $extensions)) {
        echo "This file type is not allowed.";
        $upload = false;
    }

    // Check if file upload is allowed and upload if it is
    if ($upload) {
        if (move_uploaded_file($_FILES['file']['tmp_name'], $targetFile)) {
            echo basename($_FILES['file']['name']);
        } else {
            echo "There was an error during file upload.";
        }
    }
}

Upvotes: 0

Views: 1359

Answers (1)

Cesar Bielich
Cesar Bielich

Reputation: 4945

Your code has a few issues. For one since your button was located within a Form and you were only associating a click on that button then the form was submitting itself as normal and pretty much confusing jquery. In order to capture the form properly in jquery you need to run it as a submit instead and add the e.preventDefault(); so that your code in ajax runs instead of the actual form submitting on the page.

You need to add e.preventDefault(); so that your form does not submit itself since you have form tags. Also change from click to submit

$("form").submit(function(e) {
    e.preventDefault();
    profile = "pictures/default.jpg";
    username = $("#username").val();
    email = $("#email").val();
    bio = $("#bio").val();
    newPass = $("#password").val();
    oldPass = $("#oldPass").val();
    first = $("#first").val();
    last = $("#last").val();

    // First an ajax request to upload the image as it requires separate request
    $.ajax({
        type: "POST",
        url: "upload.php?upload&type=profile",
        data: new FormData(this),
        contentType: false,
        cache: false,
        processData: false,
        success: function(resp) {
            alert(resp);
        },
        error: function (resp) {
            alert(resp);
        }
    });

    // Now the updates in the profile
    $.ajax({
        type: "POST",
        url: "update.php",
        data: "mode=details&profile="+profile+"+&username="+username+"&email="+email+"&bio="+bio+"&password="+newPass+"&oldPass="+oldPass+"&first="+first+"&last="+last,
        success: function(resp) {
            // resp contains what is echoed on update.php
            alert(resp);
        }
    });
    return false;
});

If you are dealing with multiple forms on a page, or dynamically created forms then you will want to use

$(document).on('submit', 'form', function(e) {
...
});

Even better give your form a class for dynamic data

$(document).on('submit', '.myform', function(e) {
...
});

Upvotes: 1

Related Questions