AJAX Form refreshing page when using move_uploaded_file() - php

I've built a simple form that posts data using jQuery AJAX to a PHP endpoint.
Everything works fine and the data is all being posted correctly.
The problem I am having is once the file is added to the input and submitted, the page refreshes. It doesn't refresh if I don't add the file, and doesn't refresh if I take the file input out altogether. Only when the file is successfully moved.
I need the page not to refresh, hence the use of AJAX in the first place.
Form:
<form id="form-send">
<div class="c-form-group grid-2">
<label for="first_name">First Name</label>
<input class="c-form-control" type="text" id="first_name" name="first_name" placeholder="Joe" value="Joe">
</div>
<div class="c-form-group grid-2">
<label for="file">Add File</label>
<input class="c-form-control c-form-control--file" type="file" id="file" name="file">
</div>
<div class="c-btn-group">
<button id="send" class="c-btn c-btn--primary" type="submit">Submit</button>
</div>
</form>
Ajax:
$("#form-send").on('submit', function(e){
e.preventDefault();
$.ajax({
type: "POST",
enctype: 'multipart/form-data',
url: '/send-form.php',
cache: false,
processData: false,
contentType: false,
data: new FormData(this),
success: function(data) {
console.log(data);
},
error: function(response) {
console.log('An error ocurred.');
},
});
})
Endpoint:
<?php
$uploadDir = 'uploads/';
// If post
if (isset($_POST)) {
// Request Values
$firstname = $_REQUEST['firstname'];
$file = $_REQUEST['file'];
// Upload to folder
if(!empty($_FILES["file"]["name"])){
// File path config
$fileName = basename($_FILES["file"]["name"]);
$targetFilePath = $uploadDir . $fileName;
$fileType = pathinfo($targetFilePath, PATHINFO_EXTENSION);
// Allow certain file formats
$allowTypes = array('pdf', 'doc', 'docx', 'jpg', 'png', 'jpeg');
if(in_array($fileType, $allowTypes)){
// Upload file to the server
if(move_uploaded_file($_FILES["file"]["tmp_name"], $targetFilePath)){
echo "Success: File uploaded.";
} else {
echo "Error: Something went wrong.";
}
} else{
echo "Error: File is not the correct format.";
}
}
}
?>

As the ajax call is asynchronous, you have to prevent the form from submitting, and then when a result is returned, you check if it matches the condition and submit the form with the native submit handler, avoiding the preventDefault() in the jQuery event handler :
$("#form-send").on('submit', function(e){
e.preventDefault();
$.ajax({
type: "POST",
enctype: 'multipart/form-data',
url: '/send-form.php',
cache: false,
processData: false,
contentType: false,
data: new FormData(this),
success: function(data) {
console.log(data);
},
error: function(response) {
console.log('An error ocurred.');
},
});
});
You can remove the form tag that is responsible for refreshing the page. Else, you can change button to
<button id="send" class="c-btn c-btn--primary" type="button">Submit</button>

This is how I am able to achieve in one of my projects.Hope it helps
AJAX CALL:
var form_data = new FormData();
form_data.append('title',title);
form_data.append('body',body);
form_data.append('link',link);
$.ajax
({
url: 'blog_insert.php',
dataType: 'text',
cache : false,
contentType : false,
processData : false,
data: form_data,
type: 'post',
success: function(php_script_response)
{
$("#success-message").css('display','active').fadeIn();
var title = $('#title').val(' ');
var body = $('.nicEdit-main').html('');
//$('#sortpicture').prop(' ')[0];
var link = $('#link').val('');
}
});
HTML
Blog posted successfully
<div class="form-group">
<label for="exampleFormControlInput1">Blog Title</label>
<input type="text" class="form-control" required="" name="title" id="title" placeholder="Enter your blog title">
</div>
<div class="form-group">
<label for="exampleFormControlTextarea1">Write your blog body here</label>
<textarea class="form-control" name="body" id="body" ></textarea>
</div>
<div id="dropzoneFrom" class="dropzone">
<div class="dz-default dz-message">Test Upload</div>
</div>
<div class="form-group">
<label for="exampleFormControlInput1">Reference Link</label>
<input type="text" class="form-control" id="link" name="link" placeholder="Post a reference link">
</div>
<button type="submit" id="submit-all" class="btn btn-primary" name="submit" >Post</button>

Related

How to send an image alongside other fields to PHP?

I have a jQuery function that does the insert of an image with other fields to the database. Currently my function only inserts the image but does not insert the other form fields. I am using formData object and I don't understand how to append my fields together with the image file so I can pass it to the ajax request body.
Here is what I have tried so far:
// submit function
function Submit_highschool() {
jQuery(document).ready(function($) {
$("#highschool").submit(function(event) {
event.preventDefault();
$("#progress").html(
'Inserting <i class="fa fa-spinner fa-spin" aria-hidden="true"></i></span>');
var formData = new FormData($(this)[0]);
var firstname_h = $("#firstname_h").val();
var middlename_h = $("#middlename_h").val();
formData.append(firstname_h, middlename_h);
$.ajax({
url: 'insertFunctions/insertHighSchool.php',
type: 'POST',
data: formData,
async: true,
cache: false,
contentType: false,
processData: false,
success: function(returndata) {
alert(returndata);
},
error: function(xhr, status, error) {
console.error(xhr);
}
});
return false;
});
});
}
// html form
<form method="post" enctype="multipart/form-data" id="highschool">
<div class="card" id="highschool">
<div class="col-3">
<label for="firstname">First name *</label>
<input type="text" class="form-control" id="firstname_h" placeholder="First name" />
</div>
<div class="col-3">
<label for="middlename">Middle name *</label>
<input type="text" class="form-control" id="middlename_h" placeholder="Middle name" />
</div>
<div class="col-6">
<label for="grade11_h">Grade 11 Transcript (image) *</label>
<input type="file" class="form-control" name="grade11_h" id="grade11_h" accept=".png, .jpg, .jpeg">
</div>
<button type="submit" name="submit" class="btn btn-primary float-right" onclick="Submit_highschool();">Submit</button>
</div>
</form>
The image name is succesfully inserted in the db and the image is uploaded to the required target location,However, the fields - firstname and middlename are not inserted and I don't understand how to append these properties to the formData.
How can I pass these fields to the formData please?
You can use the following approach for storing the data with image.
1.In PHP API write logic for Upload image to server using move_uploaded_file() & Insert image file name with server path in the MySQL database using PHP.
2.In JS/JQuery, Read all HTML element & create an object & POST it to the API using AJAX Call.
your JS code should be like this. Hope this will help you to fix the issue.
var RegObj = {
'Field1': $("#Field1").val(),
'Field2': $("#Field2").val(),
'logo': $("#company_logo").attr('src'),
}
console.log(RegObj);
$.ajax({
url: "API_PATH_HERE",
type: "POST",
data: JSON.stringify(RegObj),
headers: {
"Content-Type": "application/json"
},
dataType: 'text',
success: function (result) {
//
},
error: function (xhr, textStatus, errorThrown) {
}
});
Like #Professor Abronsius suggested in the comments section I only needed to add the "name" tag to the form elements and remove the append from my function thus, I have edited the function and the form as follows:
// since I have added the name tag to the form elements, there is now
// no need to use the append() thus, I have commented out the append
// lines.
function Submit_highschool() {
jQuery(document).ready(function($) {
$("#highschool").submit(function(event) {
event.preventDefault();
$("#progress").html(
'Inserting <i class="fa fa-spinner fa-spin" aria-hidden="true"></i></span>');
var formData = new FormData($(this)[0]);
// var firstname_h = $("#firstname_h").val(); // removed this
// var middlename_h = $("#middlename_h").val(); // removed this
//formData.append(firstname_h, middlename_h); // removed this
$.ajax({
url: 'insertFunctions/insertHighSchool.php',
type: 'POST',
data: formData,
async: true,
cache: false,
contentType: false,
processData: false,
success: function(returndata) {
alert(returndata);
},
error: function(xhr, status, error) {
console.error(xhr);
}
});
return false;
});
});
}
// added the "name" tag to the form elements
<form method="post" enctype="multipart/form-data" id="highschool">
<div class="card" id="highschool">
<div class="col-3">
<label for="firstname">First name *</label>
<input type="text" class="form-control" name="firstname_h" id="firstname_h" placeholder="First name" /> // added name="firstname_h"
</div>
<div class="col-3">
<label for="middlename">Middle name *</label>
<input type="text" class="form-control" name="middlename_h" id="middlename_h" placeholder="Middle name" /> // added name="middlename_h"
</div>
<div class="col-6">
<label for="grade11_h">Grade 11 Transcript (image) *</label>
<input type="file" class="form-control" name="grade11_h" id="grade11_h" accept=".png, .jpg, .jpeg">
</div>
<button type="submit" name="submit" class="btn btn-primary float-right" onclick="Submit_highschool();">Submit</button>
</div>
</form>

Problem in pass form and file data with ajax and jQuery

I want to pass some form data and file to a flask application from a form. but I can't pass it with ajax. There is a problem in data I guess. I've send data in ajax but in flask application I don't get any string or files.
Here is my html code:
<form id="user_vote" enctype = "multipart/form-data">
<br>
<br>
<div class="row">
<label class="col-sm-2">Name:</label>
<div class="col-sm-10">
<input type="text" name="name" id="name" rows="2" class="form-control" required>
</div>
</div>
<div class="row">
<label class="col-sm-2">National ID Image:</label>
<div class="col-sm-10">
<input type="file" name="national_id_image" id="national_id_image" rows="2" class="form-control" required>
</div>
</div>
<br>
<div class="row">
<label class="col-sm-2">Vote:</label>
<div class="col-sm-10">
<input type="number" name="vote" id="vote" rows="2" class="form-control" required>
</div>
</div>
<div class="row">
<div class="col-lg-12 text-center">
<input type="button" id="submit_vote" class="btn btn-primary btn-lg"
value="Authenticate and Encrypt Vote">
</div>
</div>
And here is my ajax code::
$(function(){
var form = $('#user_vote')[0];
var data = new FormData(form);
//console.log('hello');
//console.log(document.getElementById('submit_vote'));
$('#submit_vote').click(function(){
//console.log(data);
//console.log('hello');
$.ajax({
url: '/encrypt/vote',
type: "POST",
dataType: 'json',
enctype: 'multipart/form-data',
data: data,
contentType: false,
cache: false,
processData:false,
success: function(response){
//console.log("SUCCESS : ", data);
document.getElementById("encrypted_vote").innerHTML = response['encrypted_vote'];
document.getElementById("public_key").innerHTML = response['signature'];
document.getElementById("warning").style.display = "block";
},
error: function(error){
console.log(error);
}
});
});
})
Flask codes::
app.route('/encrypt/vote', methods=['POST'])
def encrypt_vote():
print('test')
name = request.form['name']
print(name)
family_name = request.form['family_name']
birth_date = request.form['birth_date']
national_id = request.form['national_id']
file = request.files['national_id_image']
filename = str(name) + str(family_name)# + secure_filename(file.filename)
#file.save(os.path.join(app.root_path, UPLOAD_FOLDER, filename))
#voter_national_cart_hash = get_digest('files/uploads/' + filename)
print('test vote type')
print(request.form['vote'])
vote = int(float(request.form['vote']))
pk = int(float(request.form['public_key']))
encrypted_vote = encrypt(pk, vote)
response = {
'encrypted_vote': str(encrypted_vote)
}
return jsonify(response), 200
Anyone can help me??
Thanks
It seems that you set enctype: 'multipart/form-data', which is non-existent property of the $.ajax() method. You should correct this error and simplify the request:
$.ajax({
type: "POST",
data: data,
url: '/encrypt/vote',
cache: false,
contentType: false,
processData: false,
success: function(response) {
/*The rest of your code*/
},
error: function(error){
console.log(error);
}
});
There is no need to set dataType, the default is Intelligent Guess (xml, json, script, or html). Read more here.
EDIT: Make sure you are using correct full path in the url, try not to use relative address, use https://www.your-server.com/encrypt/vote instead.

AJAX post form with file upload

I have this problem that i cant seem to solve, for sure is a noob thing but here it goes, i'm trying to past values and upload file using the same form, but the file is not passing to the php function.
my html with ajax:
<form name="create_batch" method="post" role="form">
<input type="hidden" name="token" value="<?= \Middlewares\Csrf::get() ?>" required="required" />
<input type="hidden" name="request_type" value="create" />
<input type="hidden" name="project_id" value="<?= $data->project->project_id ?>" />
<input type="hidden" name="type" value="batch" />
<div class="notification-container"></div>
<div class="form-group">
<label><i class="fa fa-fw fa-signature fa-sm mr-1"></i> <?= $this->language->create_link_modal->input->location_url ?></label>
<input type="text" class="form-control" name="location_url" required="required" placeholder="<?= $this->language->create_link_modal->input->location_url_placeholder ?>" />
</div>
<div class="form-group">
<input type="file" name="file">
</div>
<div class="form-group">
<label><i class="fa fa-fw fa-link"></i> <?= $this->language->create_link_modal->input->url ?>
</label>
<input type="text" class="form-control" name="url" placeholder="<?= $this->language->create_link_modal->input->url_placeholder ?>" />
</div>
<div class="text-center mt-4">
<button type="submit" name="submit" class="btn btn-primary"><?= $this->language->create_link_modal->input->submit ?></button>
</div>
</form>
<script>
$('form[name="create_batch"]').on('submit', event => {
$.ajax({
type: 'POST',
url: 'link-ajax',
data: $(event.currentTarget).serialize(),
success: (data) => {
if(data.status == 'error') {
let notification_container = $(event.currentTarget).find('.notification-container');
notification_container.html('');
display_notifications(data.message, 'error', notification_container);
}
else if(data.status == 'success') {
/* Fade out refresh */
fade_out_redirect({ url: data.details.url, full: true });
}
},
dataType: 'json'
});
event.preventDefault();
})
</script>
this will post the data to the php file and the respective funtion, but only the fields are passing through. The file, that is a csv, is not passing. for sure i have something wrong on my ajax script that is only allow to pass the values of the form via post but not the file.
my php is something like this:
<?php
if(!empty($_FILES)){
$fh = fopen($_FILES['file']['tmp_name'], 'r+');
$i=0;
$lines = array();
while( ($row = fgetcsv($fh, 8192)) !== FALSE ) {
$lines[] = $row;
$location_url = $lines[$i][0];
$url = $lines[$i][1];
$umt_source = $lines[$i][2];
$utm_medium = $lines[$i][3];
$utm_campaign = $lines[$i][4];
$utm_term = $lines[$i][5];
$utm_content = $lines[$i][6];
$i=$i+1;
}
fclose($fh);
}
$_POST['project_id'] = (int) $_POST['project_id'];
$_POST['location_url'] = trim(Database::clean_string($_POST['location_url']));
$_POST['url'] = !empty($_POST['url']) ? get_slug(Database::clean_string($_POST['url'])) : false;
...........
Any help? Many thanks.
In order to send multipart form data, you need to create and send a form data object.
see example below -
var formdata = new FormData($('#formId')[0]);
$.ajax({
url: URL,
type: 'POST',
dataType: 'json',
async: false,
cache: false,
contentType: false,
processData: false,
data: formdata,
success: function (response) {
$('#responseMsg').html(response.msg);
}
});
On server end you can get your data by $_POST and files by $_FILES
the solution.
$("form#create_batch").submit(function(e) {
e.preventDefault();
var formData = new FormData(this);
$.ajax({
url: 'link-ajax',
type: 'POST',
data: formData,
dataType: 'json',
success: (data) => {
if(data.status == 'error') {
let notification_container = $(event.currentTarget).find('.notification-container');
notification_container.html('');
display_notifications(data.message, 'error', notification_container);
}
else if(data.status == 'success') {
/* Fade out refresh */
fade_out_redirect({ url: data.details.url, full: true });
}
},
cache: false,
contentType: false,
processData: false
});
});

image upload using ajax in Laravel

I have an user information form in my Laravel site and trying to upload image using Ajax.
Blade
<form id="edit_form" enctype="multipart/form-data">
<input type="hidden" name="_token" id="csrf-token" value="{{ Session::token() }}" />
<div class="form-group">
<label>Image</label>
<input id="edit_form_image" type="file" class="form-control" name="user_image">
</div><!-- end form-group -->
<div class="form-group">
<label>Name</label>
<input id="edit_form_name" type="text" class="form-control" value="{{Auth::user()->name}}">
</div><!-- end form-group -->
<button type="button" id="edit_form_submit" class="btn btn-orange">Save Changes</button>
Ajax
$('#edit_form_submit').click(function(event) {
var fd = new FormData();
var edit_form_image = $('#edit_form_image')[0].files;
var edit_form_name = $('#edit_form_name').val();
var token = $('input[name=_token]').val();
fd.append( 'image', edit_form_image );
fd.append( 'name', edit_form_name );
fd.append( '_token', token );
$.ajax({
url:"{{ url('/profile-update') }}",
data: fd,
async:false,
type: 'POST',
processData: false,
contentType: false,
success:function(msg)
{
console.log(msg);
}
});
});
But in my controller I can't get the image file.
controller
if (request()->hasFile('image'))
{
return "file present";
}
else{
return "file not present";
}
Though I upload an image controller always response that `file no present'.
Where is the error? Anybody Help please ?
why dont you name your input tags as you need to send in post method in :
<input name="image" id="edit_form_image" type="file" class="form-control">
<input name="name" id="edit_form_name" type="text" class="form-control" value="{{Auth::user()->name}}">
And,
$("#edit_form").on('submit',(function(e) {
e.preventDefault();
$.ajax({
url:"{{ url('/profile-update') }}",
type: "POST",
data: new FormData(this),
processData: false,
contentType: false,
success:function(msg)
{
console.log(msg);
}
});
});
This might works.

How to upload the file without submitting the form?

I am trying to upload a file with ajax and php without page refresh and for submit.
my code is able to run and alert the valid message if I just do the preg_match, but when I add the rest of the validation which need to use the $_FILES[$filrec]["tmp_name"], it won't alert me the valid message.
What is wrong here? isn't it possible to upload the file without submitting the form with the following method?
There are bunch of different suggestions and examples with more complicated javascript or jquery methods, but I am trying to simply the ajax and leave the rest for PHP. is that possible with my bellow ajax function ?
Javascript :
var fileselected = $("#browse").val().replace(/C:\\fakepath\\/i, '');
setTimeout(function() {
$.ajax({
type: 'POST',
url: "ajax/extval.php",
data: {fileprs: fileselected},
dataType: 'json',
cache: false,
success: function(resuval) {
// file validation result
if (resuval === "valid"){
alert ("valid")
PHP :
<form id="upload" method="post" class="<?php echo $orvalue."<separator>".$user_id ?>" action="" enctype="multipart/form-data">
<div id="formcontent">
<label class="required" for="unitprice" title="Unit price"><input type="text" id="unitprice" name="unitprice" />Unit price</label>
<label class="required" for="qty" title="How many pcs"><input type="text" id="qty" name="qty" />Quanity</label>
<label class="required" for="express" title="Express within China"><input type="text" id="express" name="express" />Express</label>
<label class="required" for="linkURL" title="Insert a full URL http:\\"><input type="text" id="linkURL" name="linkURL" />Link</label>
<label for="yourdesc" title="Describe your need clearly"><textarea id="yourdesc" name="yourdesc"></textarea>Description<li><font size="-2">You can type 400 letters only, you typed :</li><li id="lettercounter"></li>letters</font></label>
<label for="formsubmit" class="nocontent"><input type="button" id="submitButton" href="#" class="progress-button" value="Add to order" /><strong>Note:</strong> Items marked <img src="../../images/required.jpg" alt="Required marker" width="20" height="20" /> are required fields</label>
</div>
</form>
PHP :
$filrec =mysql_real_escape_string($_POST['fileprs']);
if(preg_match("/\.(gif|png|jpg|JPG|jpeg|bmp|BMP)$/", $filrec))
{
$fileType = exif_imagetype($_FILES[$filrec]["tmp_name"]);
$allowed = array(IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG);
$allin = "valid";
echo json_encode($allin);
}
Appreciated
You can use the following PHP code to get the file received from Ajax:
$data = split(",",file_get_contents('php://input'));
$img_data = base64_decode($data[1]);
file_put_contents( 'uploads/' . $_SERVER['HTTP_X_FILENAME'],
$img_data );
You can use Following Ajax POST Request this will help you
<script>
$(document.body).on('click','.postDefects',function(){
var form_data = new FormData();
var defect = $(this).closest('tr').find( "input[name='defect_id']" ).val();
var txt_defect=$("#text_defect").val();
var upload_defect = document.getElementById("upload_defect").files[0];
form_data.append("upload_defect",upload_defect);
form_data.append("defect_id",defect_id);
form_data.append("txt_defect",txt_defect);
console.log(form_data);
$.ajax({
url:"postsample_defects.php",
method:"POST",
data: form_data,
contentType: false,
cache: false,
processData: false,
beforeSend:function(){
$('#uploaded_image').html("<label class='text-success'>Image Uploading..</label>");
},
success:function(data)
{
$('#uploaded_image').html(data);
}
});
});
</script>

Categories