I've been trying to get this done for over a week now and nothing seems to work. Users are supposed to be able to upload a file to the server with a name, but somehow AJAX is not sending anything.
This is the form where a user uploads the file:
<div class="data-attachment" data-id="">
<div class="new-attachment">
<form id="form-attachment" name="newAttachment">
<input type="text" class="attachment-name" name="name" placeholder="Name">
<input id="file" type="file" name="file" class="attachment-name">
<input type="submit" name="submit" value="Add attachment" id="submit">
</form>
</div>
<button class="btn-del">
<i class="fa fa-times"></i>
</button>
</div>
This is the function being called upon submission of the form:
$('#form-attachment').on('submit', function (e) {
e.preventDefault();
form = document.forms.namedItem('newAttachment');
formData = new FormData(form);
reader = new FileReader();
// data = {
// 'name': formData.get('name'),
// 'file': reader.readAsText($('#file')[0].files[0], 'UTF-8'),
// 'task': $('#holder').data('id')
// };
console.log(formData.get('file'));
$.ajax({
method: 'POST',
url: '/ajax/tasks/attachments/add',
data: formData,
dataType: 'json',
processData: false,
contentType: false,
success: function (response) {
alert(response);
// window.location.reload();
},
error: function (xhr, response, error) {
console.log(error);
}
})
});
This is the PHP code that recieves the form:
/**
* #param Req $request
*
* #return void
*/
public function addAttachment(Req $request)
{
if ($request->ajax()
&& $_SERVER['REQUEST_METHOD'] == 'POST'
&& $request->exists('file')
&& $request->exists('name')
&& $request->exists('task')
&& Auth::user()->hasRight('projects.tasks.attachments.add')
) {
$oTask = Task::find($_POST['task']);
if ($oTask) {
Request::file('file')->store(
'/'.$oTask->project->id, 'local'
);
$oTask->attachments()->create([
'name' => $request->input('name'),
'file' => $request->file('file')
]);
$oTask->project->logs()->save(
new Log(['description' => 'User ' . Auth::user()->nameFormatter() . ' added attachment ' . $_POST['name'] . ' to task ' . $oTask->name . ' in project ' . $oTask->project->name])
);
}
}
}
The files serve as attachments to tasks, hence the 'task' index.
I've searched through multiple similar questions and tried to apply codes from the answers but nothing seems to work. Any help or a point to the right direction is appreciated!
I see it didnt submit the file because your form is locking of enctype="multipart/form-data"
<div class="data-attachment" data-id="">
<div class="new-attachment">
<form id="form-attachment" name="newAttachment" enctype="multipart/form-data">
<input type="text" class="attachment-name" name="name" placeholder="Name">
<input id="file" type="file" name="file" class="attachment-name">
<input type="submit" name="submit" value="Add attachment" id="submit">
</form>
</div>
<button class="btn-del">
<i class="fa fa-times"></i>
</button>
</div>
also try just appending into your formData
if ($("#file")[0].files > 0) {
var file = $("#file")[0].files[0];
formData.append("file", file, file.name);
}
Related
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>
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
});
});
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>
A form within for loop, in this form user add a excel file using input type file,
for ($i = 0; $i < 4; $i++) {
<form id="TypeValidation" method="" enctype="multipart/form-data">
<input type="hidden" id="pii_categoryid" name="pii_categoryid" value="<?php echo $i;?>" />
<div>
<span class="btn btn-rose btn-round btn-file">
<span class="fileinput-new">Select File</span>
<span class="fileinput-exists">Change</span>
<input type="file" name="<?php echo $i;?>_attachment" id="<?php echo $i;?>_attachment" accept=".xlsx, .xls, .csv" />
</span>
<i class="fa fa-times"></i> Remove
<button type="submit" name="add_file" id="add_file" value="<?php echo $i;?>_file" class="btn btn-success btn-round fileinput-exists">Upload</button>
</div>
</form>
}
This form is submit using jquery here is code
$("#TypeValidation").on('submit',(function(e)
{
var pii_categoryid = $(this).find('input[name="pii_categoryid"]').val();
var fileUploadID = $(this).find('button[name="add_file"]').val();
e.preventDefault();
$.ajax({
url: "fn_dsr_wizard_submit.php?submitid="+fileUploadID,
type: "POST",
data: new FormData(this),
contentType: false,
cache: false,
processData:false,
dataType: "html",
success: function (result) {
alert(result);
//prompt("Copy to clipboard: Ctrl+C, Enter", result);
location.reload();
if(result=='1'){
location.replace("ds_dashboard.php");
}else {
location.replace("ds_dashboard.php");
}
}
});
}
));
My form show like this
When user add client excel file then it is submitted but issue is that when user add donor file or other except client excel then its not submitted.
Try assign different ID and add a class name for each form like:
<form id="TypeValidation<?php echo $i; ?>" class="my-form" method="" enctype="multipart/form-data">
In javascript:
$(".my-form").on('submit',(function(e) { ...
I downloaded a web application and i found out that it is created using Smarty Template Engine. I want to add an avatar field when creating new company so i added enctype="multipart/form-data" and <input type="file" name="avatar"> to the existing <form> and i also added avatar to my companies table in my database. Here is the HTML code:
<form class="form-horizontal" id="ib_modal_form" enctype="multipart/form-data">
<div class="form-group"><label class="col-lg-4 control-label" for="company_name">{$_L['Company Name']}<small class="red">*</small></label>
<div class="col-lg-8"><input type="text" id="company_name" name="company_name" class="form-control" value="{$val['company_name']}"></div>
</div>
<div class="form-group"><label class="col-lg-4 control-label" for="avatar">{$_L['Avatar']}</label>
<div class="col-lg-8"><input type="file" name="avatar"></div>
</div>
<div class="form-group"><label class="col-lg-4 control-label" for="email">{$_L['Email']}</label>
<div class="col-lg-8"><input type="text" id="email" name="email" class="form-control" value="{$val['email']}"> </div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" data-dismiss="modal" class="btn btn-danger">{$_L['Cancel']}</button>
<button class="btn btn-primary modal_submit" type="submit" id="modal_submit"><i class="fa fa-check"></i> {$_L['Save']}</button>
</div>
I found out that the form goes to this javascript code when clicking the Save Button:
$modal.on('click', '.modal_submit', function(e){
e.preventDefault();
$.post( _url + "contacts/add_company_post/", $("#ib_modal_form").serialize())
.done(function( data ) {
if ($.isNumeric(data)) {
location.reload();
}
else {
$modal.modal('loading');
toastr.error(data);
}
});
});
Here is the code in the Controller:
case 'add_company_post':
$data = ib_posted_data();
$company = Model::factory('Models_Company')->create();
$company->company_name = $data['company_name'];
$company->url = $data['url'];
$company->email = $data['email'];
$company->phone = $data['phone'];
$company->logo_url = $data['logo_url'];
$company->avatar = $_FILES['avatar']['name'];
$company->save();
break;
The problem is that it does not recognize $_FILES['avatar']['name']; in the Controller Whenever i add a new company, i get a NULL value in my database. I cant seem to solve this problem. Any help would be appreciated. Thanks.
Change
From
$("#ib_modal_form").serialize()
To
new FormData($("#ib_modal_form")[0])
You should use FormData for uploading files using ajax. $(form).serialize() will give you just key and value.
Can you change your ajax call below way
$modal.on('click', '.modal_submit', function(e){
e.preventDefault();
var formData = new FormData($("#ib_modal_form")[0]);
$.ajax({
url: _url + "contacts/add_company_post/",
type: 'POST',
data: formData,
cache: false,
contentType: false,
processData: false,
success: function (data) {
if ($.isNumeric(data)) {
location.reload();
}
else {
$modal.modal('loading');
toastr.error(data);
}
},
});
});