It’s today’s need to have interactive web pages, and one of the aspects is upload pictures or files without loading the page or navigating to somewhere else.
For this here is how you can achieve it easily. Basic idea of selecting a file is the same whether you are using jquery, react, vuejs or plain vanilla javascript.
Form Markup
<form class="row" onsubmit="event.preventDefault(); submitForm()">
<div class="col-lg-6">
<img src="image_placeholder.svg" id="uploadedImage" class="img-fluid" />
</div>
<div class="col-lg-6">
<h3><label class="form-label" for="customFile">Upload File here</label></h3>
<input onchange="processFile(event)" multiple type="file" class="form-control" id="customFile" />
<button type="submit" class="btn btn-primary my-5">Upload File</button>
</div>
</form>
Note: All css classes belong to bootstrap 4. Its it used for a presentable markup. Here is how it looks like:

Javascript
The method to select file, and to send to server can be used in any javascript framework.
// FormData API is provided in javascript by default
// We will use this to send data to backend
const form_data = new FormData();
let file = null;
function processFile(e) {
// JS has 'files' array, and for single file,
// it will always be at zero index
// for multiple files, you can simply loop files array
file = e.target.files[0];
// check what do we have in this variable
// console.log(file);
}
function submitForm() {
form_data.append('file', file, file.name);
// we we use Fetch API to send post call
// Fetch is now available in javascript by default
fetch('http://localhost/ajax/fileupload', {
method: "POST",
body: form_data,
})
.then(response => response.json())
.then(data => {
console.log(data)
// you can do where you needed here
})
.catch(err => console.log(err));
return false;
}
The method processFile will select the file & add it to a variable. If we console log our variable, it gives all the necessary information, i.e name of file, file size and mime type to add validation or any other processing you need.

submitForm() method is called on form submission, and it gets the file and send to server on provided endpoint via FETCH API
In developer tool, you can see request sent to server and to make sure file is sending along with it, under FORM DATA you can see it as binary

From the server response, you can get image public url to immediately display it to user without page load:
{
"message": "File uploaded successfully!",
"image_url": "http:\/\/localhost\/ajax\/profile_picture.png"
}
Here is a Complete Code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ajax File Upload</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<style>
body {
background: #48003c;
padding-top: 10%;
}
.mainSection {
max-width: 50%;
margin-left: auto;
margin-right: auto;
background: #FFF;
padding: 20px;
}
</style>
<script>
// FormData API is provided in javascript by default
// We will use this to send data to backend
const form_data = new FormData();
let file = null;
function processFile(e) {
// JS has 'files' array, and for single file,
// it will always be at zero index
// for multiple files, you can simply loop files array
file = e.target.files[0];
// check what do we have in this variable
console.log('New File', file);
}
function submitForm() {
// here 'file' is the name by where you can get it on server
form_data.append('file', file, file.name);
// we we use Fetch API to send post call
// Fetch is now available in javascript by default
fetch('http://localhost/ajax/fileupload.php', {
method: "POST",
body: form_data,
})
.then(response => response.json())
.then(data => {
console.log('Server Response',data)
// you can do where you needed here
})
.catch(err => console.log(err));
return false;
}
</script>
</head>
<body>
<section class="mainSection container-fluid mt-5">
<h3 class="text-center mb-5">Ajax File Upload</h3>
<form class="row" onsubmit="event.preventDefault(); submitForm(event)">
<div class="col-lg-6">
<img src="image_placeholder.svg" id="uploadedImage" class="img-fluid" />
</div>
<div class="col-lg-6">
<h3><label class="form-label" for="customFile">Upload File here</label></h3>
<input onchange="processFile(event)" multiple type="file" class="form-control" id="customFile" />
<button type="submit" class="btn btn-primary my-5">Upload File</button>
</div>
</form>
</section>
</body>
</html>