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);
}
});
}));
Related
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
Having a weird issue and I'm sure it's got something to do with the way my script is grabbing the value of the file input field.
I know the controller function works because I've been able to do it by manually submitting the form without using ajax.
I also know the ajax works in sending and receiving the request because I tested it by modifying it to parse a string back and forth which worked.
Additionally I can see that the script is grabbing the file as when I select a file, it shows the selected file in the console.
In my browser I'm getting a 500 error and in Laravel I'm only getting this:
Symfony\Component\Debug\Exception\FatalThrowableError: Call to a member function getClientOriginalExtension() on string in C:\123\app\Http\Controllers\MyController.php:156
I've tried updating the controller to use Request->logo instead with no success.
View:
<form enctype="multipart/form-data" class="form-horizontal" method="POST" action="{{ url('studio/uploadLogo') }}">
{{ csrf_field() }}
<div class="form-group{{ $errors->has('studioname') ? ' has-error' : '' }}">
<label for="imageInput" class="col-md-4 control-label">Logo</label>
<div class="col-md-6">
<input data-preview="#preview" name="logo" type="file" id="imageInput">
<img id="preview" src="" style="display: none"></img>
<input class="form-control" type="submit">
</div>
</div>
</form>
Script:
$('#imageInput').change(function (e) {
e.preventDefault();
var logo = $('#imageInput').val();
console.log(logo);
$.ajax({
type: "POST",
url: '/studio/uploadLogo',
data: {logo: logo},
success: function( data ) {
console.log(data);
}
});
});
Controller:
public function uploadLogo() {
$file = Input::file('logo')->getRealPath();
$photoName = str_random(20) . '.' . Input::file('logo')->getClientOriginalExtension();
Input::get('logo')->move(public_path('avatars'), $photoName);
$response = array(
'status' => 'success',
'data' => $photoName
);
return \Response::json($response);
}
Routes:
Route::post('/studio/uploadLogo', 'MyController#uploadLogo');
Route::get('/studio/uploadLogo', 'MyController#uploadLogo');
You just change a view js script to submit like below
$('.form-horizontal').submit(function(event){
event.preventDefault();
$.ajax({
type : 'POST',
url : "/studio/uploadLogo",
data : new FormData(this),
contentType:false,
processData:false,
})
.done(function(data,status){
//Your codes here
});
});
and
echo string response from controller like below
----------------
$file=$request->file('logo');
$uploaded_file_path='';
if($file!=null) {
$destinationPath = 'uploads';
$uploaded=$file->move($destinationPath,$file->getClientOriginalName());
$uploaded_file_path= $uploaded->getPathName();
$response = array(
'status' => 'success',
'data' => $uploaded_file_path
);
}else{
$response = array(
'status' => 'failed',
'data' => $uploaded_file_path
);
}
echo json_encode($response);
----------------
Try this in your controller
public function uploadLogo() {
$file = Input::file('logo')->getRealPath();
$photoName = str_random(20) . '.' . Input::file('logo')->getClientOriginalExtension();
Input::file('logo')->move(public_path('avatars'), $photoName);
$response = array(
'status' => 'success',
'data' => $photoName
);
return \Response::json($response);
}
You have given
Input::get('logo')->move(public_path('avatars'), $photoName);
Please change it to
Input::file('logo')->move(public_path('avatars'), $photoName);
and you should submit the form from ajax as like #jalin comment (https://stackoverflow.com/a/47906201/4049692)
Hope this should be the issue.
Thanks!.
Try adding processData: false, contentType: false in your script code
$('#imageInput').change(function (e) {
e.preventDefault();
var logo = $('#imageInput').val();
var form_data = new FormData();
form_data.append("logo",$("#imageInput")[0].files[0]);
console.log(logo);
$.ajax({
type: "POST",
url: '/studio/uploadLogo',
data: {form_data},
cache : false,
processData: false,
contentType: false
success: function( data ) {
console.log(data);
}
});
});
And try getting values in controller like $request->logo
Refer my answer here enter link description here
add data into FormData instance using 'this' and pass it to the data object in the ajax, also add contentType: false, processData: false
let formData = new FormData(this);
$.ajax({
type: "POST",
url: "{{ route('auth.societies.store') }}",
contentType: false,
processData: false,
});
then it will upload the form images
I have a PHP function that creates dynamic created division. Each of these divisions have a different data-type and a button. How do I retrieve the data-type of a division when the user clicks on the submit button using Javascript?
PHP CODE:
function html_submit_docs($docname,$datasubmit){
$html .= '<section class="docs">';
$html .=
'<div class="card_doc">
<div class="custome-file" data-type="'.$datasubmit.'">
<div id="label">
Upload Your Document
</div>
<input type="file" />
<button id="upload" value="Upload" />
</div>
</div>';
$html .= '</section>';
return $html;
}
JAVASCRIPT CODE:
$(document).on('click', '#upload', function() {
console.log('button activattion');
var form_data = new FormData();
var doctype = $(this).closest('div').find('data-type').attr('data-type');
console.log(doctype);
jQuery.ajax({
type: 'POST',
url: ajaxobject.ajaxurl,
cache: false,
contentType: false,
processData: false,
data: {
action: 'upload_submit_docs',
testuser: ajaxobject.student_id,
doctype: doctype,
form_data: form_data
},
dataType: 'json',
success: function(response) {
console.log(response);
},
error: function(err) {
console.log('err', err)}
});
})
Since you are using jQuery you can use data():
var doctype = $(this).closest('div').data('type');
I created a function in laravel that raises some pictures together and returns their names, so I can view them immediately on the page without having to refresh the browser. I want to allow deleting a photo, but it does not give that return values through JSON are not in the DOM. What am I doing wrong?
HTML:
<form action="" enctype="multipart/form-data" id="data">
<input type="file" name="image[]" multiple>
<button type="submit">send</button>
</form>
<hr>
<div class="returns_img"> </div>
<script type="text/javascript">
$("form#data").submit(function(event){
event.preventDefault();
var formData = new FormData($(this)[0]);
$.ajax({
url: "upimage",
type: "POST",
data: formData,
async: false,
success: function(msg){
$(".returns_img").append(msg);
},
cache: false,
contentType: false,
processData: false
});
});
$("#dell_msg").click(function(){
$(".up_side").removeClass(".list_img");
});
Routes.php:
Route::post('upimage', function(){
foreach (Input::file("image") as $image) {
$imagename = time(). $image->getClientOriginalName();
$upload = $image->move(public_path() . "/img/",$imagename);
if ($upload) {
$uploaddata [] = $imagename;
}
echo "<div class='list_img'><img src='/img/". $imagename. "'><button id='dell_msg'>X</button> </div>";
}
I newbie in this webpage area and I was try to upload image to my file by using ajax and send it to php. But I have done some coding here. Can some one correct me where I'am wrong ?
here is my form with file upload and a button
<form method="post" enctype="multipart/form-data" action="">
<input type="file" name="images" id="images" multiple="" />
<input type="submit" value="submit" id="harlo">
</form>
Once I click on button the file will send it here and receive the src and ajax to php file
but I guess is about getting source problem. Need some one correct it for me.
(function upload() {
var input2 = document.getElementById("harlo"),
formdata = false;
if (window.FormData) {
formdata = new FormData();
}
input2.addEventListener("click", function () {
var i = 0, len = $('input[type="file"]')[0].files;
for ( ; i < len.length; i++ ) {
file = len.files[i];
if (formdata) {
formdata.append("images", file);
}
}
if (formdata) {
$.ajax({
url: "upload.php",
type: "POST",
data: formdata,
processData: false,
contentType: false,
success: function (res) {
document.getElementById("response").innerHTML = res;
}
});
}
}, false);
}());
<?php
foreach ($_FILES["images"]["error"] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
$name = $_FILES["images"]["name"][$key];
move_uploaded_file( $_FILES["images"]["tmp_name"][$key], "uploads/" . $_FILES['images']['name'][$key]);
}
}
echo "<h2>Successfully Uploaded Images</h2>";
?>
Use something like:
$("form").on("submit", function(
// Your ajax request goes here
$.ajax({
url: "upload.php",
type: "POST",
data: $("form").serialize(),
processData: false,
contentType: false,
success: function (res) {
$("#response").innerHTML = res;
}
});
return false;
));
But there seems to be a problem with sending files trough ajax anyway. Cause they're missed by the serialize() method because JS has no access to files content on users computer. So the form must be sent to the server to get the file data.
See here: https://stackoverflow.com/a/4545089/1652031