I am facing a problem during images upload.
I have an input type file control in my form and more input controls can be added using jquery. The problem is this: when I get all those control values, it only return the first value from file control.
How can I get all added files in all control? Here is my code:
Javascript
$(document).ready(function() {
$('#add_more').click(function() {
$(this).before($("<div/>", {
id: 'filediv'
}).fadeIn('slow').append(
$("<input/>", {
name: 'file[]',
type: 'file',
id: 'file',
accept: '.jpg, .jpeg, .gif'
}),
$("<br/><br/>")
));
});
$('#upload').click(function(e) {
var name = $(":file").val();
if (!name) {
alert("File Must Be Selected");
e.preventDefault();
} else {
//upload all images
var fileData = $('#file').prop("files")[0];
var form_data = new FormData();
form_data.append('file', fileData);
$.ajax({
url: "myurl.php",
dataType: 'text',
data: form_data,
cache: false,
contentType: false,
processData: false,
type: "post",
error: function() {
alert('error');
},
success: function(ret) {
alert('sucess');
}
});
}
}
});
HTML
<form enctype="multipart/form-data" action="" method="post">
<hr/>
<div id="filediv">
<input name="file[]" type="file" id="file" accept=".jpg, .gif, .jpeg" />
</div>
<br/>
<input type="hidden" value="" id="class" name="class">
<input type="button" id="add_more" class="upload" value="Add More Files" />
<input type="button" value="Upload File" name="submit" id="upload" class="upload" />
</form>
When I get the post from php using $_FILES['file']['name'] and counting it using
count($_FILES['file']['name']) it returns 1.
When I process further, only the first file is uploaded in the corresponding folder.
Something is probably wrong on line var fileData = $('#file').prop("files")[0];.
Your JS Code should be as below :
$(document).ready(function () {
$('#add_more').click(function () {
$(this).before($("<div/>", {
id: 'filediv'
}).fadeIn('slow').append(
$("<input/>", {
name: 'file[]',
type: 'file',
// Id must be unique
// id: 'file',
class: "file_input",
accept: '.jpg, .jpeg, .gif'
}),
$("<br/><br/>")
));
});
$('#upload').click(function (e) {
var boolAreAllFilesSelected = true;
var objFormData = new FormData();
$.each($(":file"), function ( ) {
if (!$(this).val())
{
alert("File Must Be Selected");
$(this).focus();
return boolAreAllFilesSelected = false;
}
else
{
objFormData.append('file[]', $(this).prop("files")[0]);
}
});
if (boolAreAllFilesSelected)
{
$.ajax({
url: "myurl.php",
dataType: 'text',
data: objFormData,
cache: false,
contentType: false,
processData: false,
type: "post",
error: function () {
alert('error');
},
success: function (ret) {
alert('sucess');
}
});
}
});
});
Your PHP Code should be as below :
<?php
function uploadSingleImage($arrSingleFile = array())
{
if (!empty($arrSingleFile))
{
// Here your image uploading code
}
}
if (!empty($_FILES['file']))
{
$arrFile = $_FILES['file'];
foreach ($arrFile['name'] as $intIndex => $strName)
{
$arrSingleFile["name"] = $strName;
$arrSingleFile["type"] = $arrFile['type'][$intIndex];
$arrSingleFile["tmp_name"] = $arrFile['tmp_name'][$intIndex];
$arrSingleFile["error"] = $arrFile['error'][$intIndex];
$arrSingleFile["size"] = $arrFile['size'][$intIndex];
uploadSingleImage($arrSingleFile);
}
}
else
{
die("You have not uploaded any file.");
}
Related
I want to upload multiple files using onchange in laravel 8. is it possible to upload just by onchange? I have this html form. I hope you can help me guys. thanks
<form method="POST" enctype="multipart/form-data" id="upload_form">
#csrf
<input type="file" name="file[]" id="file" multiple >
</form>
this is my Jquery and Ajax Script.
<script>
function uploadfile(){
var formData = new FormData($('#upload_form')[0]);
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
type:'POST',
url: "{{ route('dropzone-action') }}",
data: formData,
contentType: false,
processData: false,
success: (response) => {
if (response) {
this.reset();
alert('Image has been uploaded successfully');
}
},
error: function(response){
console.log(response);
$('#image-input-error').text(response.responseJSON.errors.file);
}
});
}
and here is my controller
function action(Request $request){
$request->validate([
'file' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
if($request->hasFile('file')){
foreach($request->file as $file) {
$completeFileName = $file->getClientOriginalName();
$fileNameOnly = pathinfo($completeFileName, PATHINFO_FILENAME);
$extension = $file->getClientOriginalExtension();
$file->storeAs('uploads', $completeFileName);
}
}
return response()->json('Image uploaded successfully');
}
You can call change method
$("#file").change(function() {
uploadfile();
});
and in validation
$request->validate([
'file.*' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
and in controller
function action(Request $request){
$request->validate([
'file.*' => 'required|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
]);
foreach($request->file as $file) {
if($file!=null){
$completeFileName = $file->getClientOriginalName();
$fileNameOnly = pathinfo($completeFileName, PATHINFO_FILENAME);
$extension = $file->getClientOriginalExtension();
$file->storeAs('uploads', $completeFileName);
}
}
return response()->json('Image uploaded successfully');
}
I'm trying to send a file using AJAX with the form but the PHP file seems to receive nothing, not only the files but also the form elements. In PHP if i try to get a value from the $_POST i get an Undefined Index.
I've tried:
$("#animal-insert").click((e) => {
e.preventDefault();
var fd = $("#animal-form-input");
var files = $("#file")[0].files[0];
fd.append("file", files);
$.ajax({
url: "php_utility/ajax/admin-animal.php",
type: "post",
data: fd,
cache: false,
contentType: false,
processData: false,
success: function (response) {
console.log(response);
if (response === "allok") {
showModalError("Registrato Correttamente", "modalsuccess");
} else {
showModalError("Non Registrato Correttamente", "modalerror");
}
},
});
and the method you see in the code below. I'm restricted to do this without plugins.
I was also trying with the $.post() but if i understood correctly i have to use $.ajax() to add the processData: false to send files.
HTML
<form method="POST" action="" id="animal-form-insert" enctype="multipart/form-data">
<div class="span-1-of-2">
<label for="specie" class="label">Specie Animale:</label>
<input type="text" class="animal-input" id="specie" name="specie" required placeholder="Pavo cristatus">
<label for="an-name" class="label">Nome Comune:</label>
<input type="text" class="animal-input" id="an-name" name="an-name" required placeholder="pavone comune">
</div>
<div class="span-1-of-2">
<label for="biom" class="label">Bioma/Habitat:</label>
<select class="animal-input" name="biom" id="biom" required>
<option value="Savana">Savana</option>
<option value="Tundra">Tundra</option>
<option value="Pianura">Pianura</option>
</select>
<label for="zoo-zone" class="label">Zona Zoo:</label>
<select class="animal-input" name="zoo-zone" id="zoo-zone">
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="F">F</option>
<option value="PN">PN</option>
</select>
</div>
<label for="animal-photo" class="label">Foto Animale:</label>
<input type="file" id="animal-photo" name="animal-photo" accept=".jpg,.jpeg.png" required>
<label for="aniaml-desc" class="label">Descrizione:</label>
<textarea class="animal-input-desc" name="animal-desc" id="animal-desc" required></textarea>
<button type="submit" name="animal-insert" id="animal-insert" class="btn btn-block">Aggiungi</button>
</form>
JS
$("#animal-insert").click((e) => {
e.preventDefault();
var formData = {
specie: $("#specie").val(),
anname: $("#an-name").val(),
biom: $("#biom").val(),
zoozone: $("#zoo-zone").val(),
animaldesc: $("#animal-desc").val(),
animalphoto: $("#animal-photo")[0].files[0],
submit: "submit",
};
console.log(formData);
$.ajax({
url: "php_utility/ajax/admin-animal.php",
type: "post",
data: JSON.stringify(formData),
cache: false,
contentType: false,
processData: false,
success: function (response) {
console.log(response);
if (response === "allok") {
showModalError("Registrato Correttamente", "modalsuccess");
} else {
showModalError("Non Registrato Correttamente", "modalerror");
}
},
});
});
PHP
<?php
error_log($_POST['specie']);
if (isset($_POST['specie'])) {
$animalspecie = $_POST['specie'];
$animalName = $_POST['anname'];
$animalBiom = $_POST['biom'];
$animalZone = $_POST['zoozone'];
$animalDesc = $_POST['animaldesc'];
$animalPhoto = $_FILES['animalphoto'];
$animalPhotoName = $animalPhoto['name'];
$photoTmp = $animalPhoto['tmp_name'];
$photoErr = $animalPhoto['error'];
$photoType = $animalPhoto['type'];
error_log("not here");
$formats = ["image/jpg", "image/jpeg", "image/png"];
require_once '../sql/utility.php'; //file with functions for db
require_once '../checks.php'; //file with some type checks
if (empty($animalspecie) || empty($animalName) || empty($animalBiom) || empty($animalZone) || empty($animalDesc) || empty($animalPhoto)) {
echo "emptyinput";
exit();
}
if (!preg_match('/[A-Z]+[a-z]+\s[a-z]+/', $animalspecie)) {
echo "invalidspecie";
exit();
}
if (!in_array($photoType, $formats)) {
echo "invalidformat";
exit();
}
if ($photoErr !== 0) {
echo "fileerror";
exit();
}
$tmpExtension = explode("/", $photoType);
$photoExtension = end($tmpExtension);
$photoNewName = preg_replace('/\s+/', '', $animalName) . preg_replace('/\s+/', '', $animalName) . "." . $photoExtension;
$photoDestination = "//resurces/images/animals/" . $photoNewName;
move_uploaded_file($photoTmp, $_SERVER['DOCUMENT_ROOT'] . $photoDestination);
$result = insertAnimal($conn, $animalspecie, $animalName, $animalBiom, $animalZone, $animalDesc);
echo $result;
}
You should create a new FormData() and append your form values and files to it, and then send it as 'multipart/form-data' in the data (not body) param.
$("#animal-insert").click((e) => {
e.preventDefault();
var formData = new FormData();
formData.append("specie", $("#specie").val())
formData.append("anname", $("#an-name").val())
formData.append("biom", $("#biom").val())
formData.append("zoozone", $("#zoo-zone").val())
formData.append("animaldesc", $("#animal-desc").val())
formData.append("animalphoto", $("#animal-photo")[0].files[0])
formData.append("submit", "submit")
$.ajax({
url: "php_utility/ajax/admin-animal.php",
method: "post",
data: formData,
cache: false,
mimeType: "multipart/form-data",
contentType: false,
processData: false,
success: function (response) {
console.log(response);
if (response === "allok") {
showModalError("Registrato Correttamente", "modalsuccess");
} else {
showModalError("Non Registrato Correttamente", "modalerror");
}
},
});
});
In PHP Your files will be avaiable in $_FILES array, and the other data will be in $_POST array.
More on FormData: https://developer.mozilla.org/en-US/docs/Web/API/FormData
I've seen and tried a few answers that are similar to this question, but it still displays the same error.
The console is also giving the error: Uncaught TypeError: Cannot read property 'length' of undefined at Function.each (jquery-1.10.2.js:631)
My view:
<form action="https://dev.vmc.w3.uvm.edu/xana/sensors/deployments" class="basicForm aboutForm form-horizontal" id="deploymentForm" enctype="multipart/form-data" method="post" accept-charset="utf-8">
<div class="form-group">
<label for="fldFileName" class="col-sm-4 control-label">Image</label>
<div class="col-sm-8">
<input type="file" name="fldFileName" value="" class="form-control" id="fldFileName" />
</div>
</div>
<button type="button" class="btn btn-primary" id="newSensorSubmit">Save</button>
</form>
javascript to submit form:
$(document).on("click", "#newSensorSubmit", function(event){
var posturl="<?php echo site_url("sensors/add_deployment");?>";
var formData = new FormData();
var fldFileName = $('#fldFileName').val();
formData.append('fldFileName', fldFileName);
jQuery.ajax({
url: posturl,
data: formData,
cache: false,
mimeType: "multipart/form-data",
dataType: 'json',
contentType: false,
processData: false,
type: 'POST',
success: function(data){
if(data.status === 'success') {
//handle success
}
else {
//handle fail
}
},
error: (error) => {
$('#articleErrorText').html(JSON.stringify(error));
}
});
});
controller:
public function add_deployment(){
$this->load->helper(array('form', 'url'));
$this->load->library('upload');
$config = array(
'upload_path' => site_url("attachments/project/999/metstations"),
'allowed_types' => "gif|jpg|png|jpeg",
'overwrite' => TRUE,
'max_size' => "16000000"
);
$this->load->library('upload', $config);
if($this->upload->do_upload('fldFileName'))
{
$data['image_metadata'] = array('image_metadata' => $this->upload->data());
}
else
{
$error = $this->upload->display_errors();
$data['errors']='<p class="error-message">'.$error.'</p>';
$data['status']='failure';
}
}
Try This.
To get all your form inputs, including the type="file" you need to use FormData object.
To append param just use append() method:
formData.append("param", "value");
And in the php-side I catch it:
echo $file_name = ($_FILES['file']['name']);
View Code:-
<body>
<p id="msg"></p>
<input type="file" id="file" name="file" />
<button id="upload">Upload</button>
</body>
jQuery / Ajax Code:-
<script type="text/javascript" src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function(e){
$('#upload').on('click', function () {
var file_data = $('#file').prop('files')[0];
var form_data = new FormData();
form_data.append('file', file_data);
$.ajax({
url: 'ControllerName/upload_file', // point to server-side controller method
dataType: 'text', // what to expect back from the server
cache: false,
contentType: false,
processData: false,
data: form_data,
type: 'post',
success: function (response) {
$('#msg').html(response); // display success response from the server
},
error: function (response) {
$('#msg').html(response); // display error response from the server
}
});
});
});
</script>
Controller Code:-
class ControllerName extends CI_Controller {
function __construct() {
parent::__construct();
}
function upload_file() {
//upload file
$config['upload_path'] = 'uploads/';
$config['allowed_types'] = '*';
$config['max_filename'] = '255';
$config['encrypt_name'] = TRUE; // remove it for actual file name.
$config['max_size'] = '1024'; //1 MB
if (isset($_FILES['file']['name'])) {
if (0 < $_FILES['file']['error']) {
echo 'Error during file upload' . $_FILES['file']['error'];
} else {
if (file_exists('uploads/' . $_FILES['file']['name'])) {
echo 'File already exists : uploads/' . $_FILES['file']['name'];
} else {
$this->load->library('upload', $config);
if (!$this->upload->do_upload('file')) {
echo $this->upload->display_errors();
} else {
echo 'File successfully uploaded : uploads/' . $_FILES['file']['name'];
}
}
}
} else {
echo 'Please choose a file';
}
}
}
Note:- For more reference regarding this check this
https://developer.mozilla.org/en-US/docs/Web/API/FormData/append
I have this form to change profile pic of user. I am trying to change the pic on clicking current pic and select from user filesystem
Form:
<form id="changeProfilePicForm" action="<?=base_url()?>user/change_profile_pic" method="post" accept-charset="utf-8" enctype="multipart/form-data">
<div data-content="Click To update" class="image" id="profile-image">
<input id="profile-image-upload" class="hidden" name="image" type="file" accept="image/x-png, image/gif, image/jpeg">
<?if(strlen($user['image'])){?>
<img src="<?=base_url().'uploads/profile/'.$user['image']?>" class="img-circle" alt="user profile pic" height="125px" width="125px">
<?}else{?>
<img src="<?=base_url()?>includes/img/avtar.png" class="img-circle" alt="user profile pic" height="125px" width="125px">
<?}?>
<input type="submit" class="hidden">
</div>
</form>
Javascript:
$("#changeProfilePicForm").on('submit',(function(e){
e.preventDefault();
var $form = $( this );
$.ajax({
url: $form.attr( 'action' ),
type: "POST",
data: new FormData($form),
contentType: false,
cache: false,
processData:false,
success: function(data){
console.log(data);
},
error: function(data){
console.log(data);
}
});
}));
document.getElementById('profile-image').onclick = function() {
document.getElementById('profile-image-upload').click();
};
document.getElementById('profile-image-upload').onchange = function(){
document.getElementById('changeProfilePicForm').submit();
};
PHP controller:
public function change_profile_pic()
{
$user_id = $this->session->user_id;
$image = $this->uploadimage();
if(strlen($image)){
$user_data['image'] = $image;
$updated = $this->user_model->update_user($user_id, $user_data);
$data['response'] = 1;
$data['image'] = $image;
// redirect(base_url()."user");
echo json_encode($data);
}else{
$data['response'] = 0;
$data['message'] = "error";
echo json_encode($data);
}
//redirect(base_url()."user");
}
Problem I am facing is, the form is not submitted via ajax. It is directory submitted as simple form. I can't figure out whats wrong with the code since image is being upload on simple form submission. Is there any problem with event binding or i am missing something here ?
When you call
document.getElementById('changeProfilePicForm').submit();
the submit event is not fired. Try
$('#changeProfilePicForm').trigger('submit');
Edit. Get rid of the form in html:
<input type="file" id="image">
js:
function handleUpload(event) {
var file = this.files[0];
if (!file) return;
var formData = new FormData();
formData.append('file', file);
return $.ajax({
type: 'POST',
url: '/images',
data: formData,
processData: false,
contentType: false,
//...
});
}
$('#image').on('change', handleUpload);
I believe FormData expects a native form element $form[0], not jQuery form element $form.
$("#changeProfilePicForm").submit(function (e) {
e.preventDefault();
var $form = $(this);
$.ajax({
url: $form.attr('action'),
type: "POST",
data: new FormData($form[0]),
contentType: false,
cache: false,
processData: false,
success: function (data) {
console.log(data);
},
error: function(data){
console.log(data);
}
});
}));
This question already has answers here:
How to append whole set of model to formdata and obtain it in MVC
(4 answers)
Closed 7 years ago.
I used ajax request and included upload file(image) inside the form..
Here is my code:
HTML:
#model acgs_qm.Models.StudentsData
#using (Html.BeginForm("RegisterStudent", "Admin", FormMethod.Post, new { id = "frmrs", enctype = "multipart/form-data" })){
<div id="ruCont">
<div class="first-inline">
<input type="file" id="si_image" name="si_image" accept="image/*" />
<div id="imgHolder"></div>
</div>
<div class="second-inline">
<span>Student ID:</span>
#Html.TextBoxFor(a => a.si_id, new { #class = "user-id-input"})
</div>
<div>
<span>Student Information</span>
<span class="field-name">Full Name:</span>
#Html.TextBoxFor(a => a.si_lname, new { #autocomplete = "off", #placeholder = "Last Name" })
#Html.TextBoxFor(a => a.si_fname, new { #autocomplete = "off", #placeholder = "First Name" })
#Html.TextBoxFor(a => a.si_mname, new { #autocomplete = "off", #placeholder = "Middle Name" })
</div>
<button class="ru-button" form="frmrs">Register Student</button>
</div>
}
JS:
$(document).on("submit", "#frmrs", function (e) {
e.preventDefault();
frm = $(this);
formValidation();
formData = new FormData();
file = document.getElementById("si_image").files[0];
formData.append("si_image", file);
if ($(this).valid()) {
$.ajax({
url: '/admin/registerstudent',
type: 'POST',
data: frm.serialize() + '& si_image=' + formData,
processData: false,
contentType: false,
success: function () {
$.ajax({
url: '/admin/createstudent',
type: 'GET',
success: function () {
alert('Success!')
},
error: function () {
alert('Something went wrong.')
}
});
},
error: function () {
alert('Something went wrong!');
}
});
}
});
Server Side(C#):
[HttpPost]
public ActionResult RegisterStudent(StudentsData sd, HttpPostedFileBase si_image)
{
_ActionModels ma = new _ActionModels();
if (si_image != null)
{
var versions = new Dictionary<string, string>();
var path = Server.MapPath("~/Content/profile-pic/");
versions.Add("_small", "maxwidth=500&maxheight=500&format=jpg");
foreach (var suffix in versions.Keys)
{
si_image.InputStream.Seek(0, SeekOrigin.Begin);
ImageBuilder.Current.Build(
new ImageJob(
si_image.InputStream,
path + si_image.FileName + suffix,
new Instructions(versions[suffix]),
false,
true));
}
}
ma.InsertStudentInfo(sd);
return RedirectToAction("CreateStudent");
}
The problem is that the formdata is returning a null to the controller using the HttpPostedFileBase, I don't know why it returns a null value.
Your response would be very much appreciated, thank you in advance.
Ajax send an object you will need to do somthing like this first
var Data = { Data: frm.serialize() + '& si_image=' + formData }
$.ajax({
url: '/admin/registerstudent',
type: 'POST',
data: Data,
processData: false,
contentType: false,
success: function () {
$.ajax({
url: '/admin/createstudent',
type: 'GET',
success: function () {
alert('Success!')
},
error: function () {
alert('Something went wrong.')
}
});
},
error: function () {
alert('Something went wrong!');
}
});