Hello I have been working on a site where you can submit images. I dont want the page to be reloaded when the picture is submitted. After the picture is posted to the php page it is stored a a BLOB in a MYSQL database.
form id="form2" action="saveImage.php" method="post" enctype="multipart/form-data">
<input id="thumbage2" name="Image1" class="ModalArea2" type="file" style="display:none">
<center><label for="thumbage2" id="labelthumb2" style="margin-top:35px;">Choose Image</label></center>
<button class="ModalButton2" >Submit</button>
<a class="ModalButton2" onclick="cancel2();">Cancel</a>
</form>
The above is my HTML code. Here is my javascript/jQuery code:
$(':file').change(function(){
var file = this.files[0];
var name = file.name;
var size = file.size;
var type = file.type;
//Your validation
//console.log(name);
});
$(':button').click(function(){
var formData = new FormData($('form')[0]);
$.ajax({
url: 'upload.php', //Server script to process data
type: 'POST',
xhr: function() { // Custom XMLHttpRequest
var myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){ // Check if upload property exists
myXhr.upload.addEventListener('progress',progressHandlingFunction, false); // For handling the progress of the upload
}
return myXhr;
},
//Ajax events
beforeSend: beforeSendHandler,
success: completeHandler,
error: errorHandler,
// Form data
data: formData,
//Options to tell jQuery not to process data or worry about content-type.
cache: false,
contentType: false,
processData: false
});
cancel2();
});
I copied this code from a website but they didn't do a great job of explaining how it works. So at the moment I have the data being posted to my PHP file and it works. The problem is that the PHP file is loaded. I thought the whole point of JQuery was not to load the file and to stay on the same page. Why doesn't this happen? Why do I keep getting the PHP page loaded in my browser? Thanks if you solve this for me I would be over the Moon It's been a real kick in the adams apple for me lately.
I was stuck on a similar problem once, and as far as I searched it, the only way to upload a file without reloading the page is by using iFrames. But iFrames, to me, are ugly.
The below approach converts an image into a data URL, and instead of uploading the image, uploads the data URL (which is just a string) to the server.
I've made a few changes to your HTML code. We don't want to submit the form, since that leads to the web page getting reloaded in the browser. Adding onsubmit = 'return false;' to the form tag will prevent the form from getting submitted when the submit button is clicked.
I've added a few ID's to the input elements in order to make them unique when accessed in JQuery.
Then I've added an image element with a src attribute. When the user selects an image from the input box, the src attribute of this element gets filled with the image's data URL.
<form id="form2" action="saveImage.php" onsubmit="return false;" method="post" enctype="multipart/form-data">
<input id="imageSelect" name="Image1" class="ModalArea2" type="file" style="display:block;">
<center><label for="thumbage2" id="labelthumb2" style="margin-top:35px;">Choose Image</label></center>
<button class="ModalButton2" id="uploadImageButton">Submit</button>
<a class="ModalButton2" onclick="cancel2();">Cancel</a>
<img id="imgURL" src="none"/>
</form>
Next is your JavaScript code. The comments will help you understand how it works. The main changes to it are
Added an event handler to the input button to select images. When the user selects an image using the input button, the onchange event fires and the <img> element's src attribute is filled with the image's data URL.
The second major change is to your AJAX request. I've changed it to .post, since it is simpler to read (at least to me) and inside that request, instead of sending the image itself, we are sending the image's data URL grabbed from the <img> tag's src attribute. This is sent in JSON format, so your PHP script handling the upload request should read the data in JSON format.
$(':file').change(function(){
var file = this.files[0];
var name = file.name;
var size = file.size;
var type = file.type;
//Your validation
//console.log(name);
});
$('#uploadImageButton').click(function(){
var imgData = $('#imgURL').src;
$.post({
'upload.php', // Name of the PHP script which handles upload function
{imageData:imgData}, // Use $_POST['imageData] to access the image data in your PHP script
function data() {
// whatever you want to do after the POST request is complete
alert('Uploaded image');
};
});
});
$('#imageSelect').change(function(){
readURL(this);
});
function readURL(input)
{
if(input.files && input.files[0])
{
var reader = new FileReader();
reader.onload = function(e) {
$('#imgURL').attr('src', e.target.result);
};
}
reader.readAsDataURL(input.files[0]);
}
You will need to edit your PHP script so that it reads the image's data URL in JSON format, and then saves the data URL as an image file. It should look like this:
<?php
function upload()
{
if(isset($_POST))
{
// Get the image data URL
$imageData = $_POST['imageData'];
// Replace the spaces with plus signs
$imageData = str_replace(' ', '+', $imageData);
// Decode the image data
$imageData = base64_decode($imageData);
// Path where you want to save the image
$uri = "/image.png";
// Save the image data to an image file on the server
file_put_contents($imageData, $uri);
}
}
?>
Related
im using an API to pass a whole form including images, textarea, etc.
it uses new FormData($('#form')) to pass the data into server.
everything went smooth except when i did something on <input type="file" id="upload"/>
I made the input to show the image every time the user uploads a new photo.
$(function() {
$("#upload").on("change", function()
{
var files = !!this.files ? this.files : [];
if (!files.length || !window.FileReader) return; // no file selected, or no FileReader support
if (/^image/.test( files[0].type)){ // only image file
var reader = new FileReader(); // instance of the FileReader
reader.readAsDataURL(files[0]); // read the local file
reader.onloadend = function(){ // set image data as background of div
//Showing the images here..
}
}
});
});
But now, when im submitting the form again using Ajax, it cannot read or pass the image. No image passed in the database.
Whenever i comment the line //var files = !!this.files ? this.files : []; its back to normal, but the image is not showing.
i want to ask is there an alternate way to show the image without affecting the <input type="file" tag?
Or if i have to create another <input type="file" with style="display: none;", how can i pass the image from one input with type="file" to another input with also type="file"?
I am trying to show the client an image which he has selected:
<input type="file" onchange="showImage(this)"/>
But I can't read the value of the input, as I checked out here. Is it possible to display the image?
In onchange I can send the form to server and server can send the data back, but is it really necessary? Can't the client display the data without the ping-pong to the server? Is it a security issue?
You can use FileReader web-api object for this, see this snippet:
the HTML
<input id="src" type="file"/> <!-- input you want to read from (src) -->
<img id="target"/> <!-- image you want to display it (target) -->
the javascript
function showImage(src,target) {
var fr=new FileReader();
// when image is loaded, set the src of the image where you want to display it
fr.onload = function(e) { target.src = this.result; };
src.addEventListener("change",function() {
// fill fr with image data
fr.readAsDataURL(src.files[0]);
});
}
var src = document.getElementById("src");
var target = document.getElementById("target");
showImage(src,target);
I have a script that allows the user to upload images and preview them. It's a very basic script and although I have managed to get it to do more or less everything I need I am stuck on one last thing.
As it stands once the user has uploaded an image it is displayed but if they upload another one it displays both, I would like the new image to replace the old image so only one is visible.
I don't have issues with the php side of things, the problem lies in the part where the script appends the new image to list and displays the list rather than just the new image and unfortunately my javascript knowledge is quite limited at the moment.
This is the script:
$(function(){
var btnUpload=$('#upload');
var status=$('#status');
new AjaxUpload(btnUpload, {
action: 'upload-file.php',
name: 'uploadfile',
onSubmit: function(file, ext){
if (! (ext && /^(jpg|png|jpeg|gif)$/.test(ext))){
// extension is not allowed
status.text('Only JPG, PNG or GIF files are allowed');
return false;
}
status.text('Uploading...');
},
onComplete: function(file, response){
//On completion clear the status
status.text('');
//Add uploaded file to list
if(response==="success"){
$('<li></li>').appendTo('#files').html('<img src="upload/'+file+'" alt="" /><br />'+file);
} else{
$('<li></li>').appendTo('#files').text(file);
}
}
});
});
And the images are displayed here:
<ul id="files" ></ul>
Any help will be gratefully received
Instead of:
$('<li></li>').appendTo('#files')
Try:
$('<li></li>').appendTo($('#files').empty())
This will empty the #files element before appending new content.
Is there by any chance a way of letting the user select an image from his hard drive and without submitting it to the server use this image in the browser?
I need this because I want the users to be able to crop an image before sending this cropped image to the server (thus saving a post and some bytes of data).
What I tried to do is using an input type file and then capturing the submit event, but the value from the input is just a fake path (useless).
Any help would be greatly appreciated.
Here is a very basic example (with many globals, without input validation...) of image scaling: http://jsfiddle.net/89HPM/3/ . It's using the File API and a canvas element.
As #anu said the save can be done using toDataUrl method of the canvas.
In similar way you can achieve crop.
JavaScript
(function init() {
document.getElementById('picture').addEventListener('change', handleFileSelect, false);
document.getElementById('width').addEventListener('change', function () {
document.getElementById('canvas').width = this.value;
renderImage();
}, false);
document.getElementById('height').addEventListener('change', function () {
document.getElementById('canvas').height = this.value;
renderImage();
}, false);
}());
var currentImage;
function handleFileSelect(evt) {
var file = evt.target.files[0];
if (!file.type.match('image.*')) {
alert('Unknown format');
}
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
currentImage = e.target.result;
renderImage();
};
})(file);
reader.readAsDataURL(file);
}
function renderImage() {
var data = currentImage,
img = document.createElement('img');
img.src = data;
img.onload = function () {
var can = document.getElementById('canvas'),
ctx = can.getContext('2d');
ctx.drawImage(this, 0, 0, can.width, can.height);
};
}
HTML
<input type="file" name="picture" id="picture" /><br />
<input type="text" id="width" value="200" />
<input type="text" id="height" value="200" /><br />
<canvas width="200" height="200" style="border: 1px solid black;" id="canvas"></canvas>
Here is a blog post which I made about that basic example: blog.mgechev.com
New HTML5 File API is probably the closest solution to what your looking for:
http://www.html5rocks.com/en/tutorials/file/dndfiles/
It allows you to browse for and read files within Javascript. Do whatever processing you like, and then upload to the server. Anything besides this is going to be very tricky indeed, and probably an unavoidable trip to the server and back.
Downside here is browser support.....as always
I am not sure which browsers work perfectly but HTML5 got DnD and File API. Let me give you steps which can work for you using FileAPI.
DnD API: Starts with the drop event when the user releases the mouse and the mouse-up event occurs.
DnD API: Get the DataTransfer object from the drop event
File API: Call DataTransfer.files to get a FileList, representing the list of files that were dropped.
File API: Iterate over all the individual File instances and use a FileReader object to read their content.
File API: Using the FileReader.readAsDataURL(file) call, every time a file is completely read, a new “data URL” (RFC 2397) formatted object is created and an event wrapping it is fired to the onload handler on the FileReader object.
FYI: The “data URL” object is Base64-encoded binary data, with a spec-defined header sequence of chars. Browsers understand them.
HTML5 DOM: set the image href to the File Data URL
You can't, for the following reasons:
For the reasons stated in this post: Full path from file input using jQuery
The fact that if you even try to create an img element loading a
local file path you'll get the error Not allowed to load local
resource: in your browser's console.
The fact that once you have an image in place you can only alter it's
appearance on screen and not alter the file on the system or send the altered image up to the server
You've stated that you need cross browser support, so HTML5 File API and Canvas API are out, even though they would only allow part of the functionality anyway.
I've just solved a problem closed to yours.
As everybody said you can't got the real image file address. But, you can create a temporary path and show the image in your page without submiting it to server. I'll show how easy it is, next to next paragraph.
Once you show it you can use some javascripts events to "pseudo-crop-it" and get the crop params (corners). Finaly you can add the params to some hidden field and submit the form. As a result you may use som php to crop the submited image at server and to save the result using a number of image formats as .png, jpg, gif, etc. Sorry if i do not write a complete solution, have not enough time.
/* some scripting to bind a change event and to send the selected image
to img element */
$(document.ready(function(){
$("input:file").each(function(){
var id = '' + $(this).attr('id');
var idselector = '#'+id, imgselector=idselector+'-vwr';
$(idselector).bind("change", function( event ){
(imgselector).fadeIn("fast").attr('src',
URL.createObjectURL(event.target.files[0]));
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<!-- create a img element to show the selected image and an input file element to select the image.
ID attribute is the key to have an easy and short scripting
note they are related suffix -vwr makes the difference
-->
<img src="" id="image-input-vwr" alt="image to be cropped">
<input type="file" id="image-input" name="image_input">
Hope it help some body as it is a very old question.
Luis G. Quevedo
I'm trying to upload an image using jQuery and PHP. I know there are many plugin solutions, but I'm using this. I can upload the file to the server with no problems, but for the life of me I cannot figure out how to get the file name so I can show the image. Is there any way to get the file name from the iframe I post to? Here is the code I am working with:
jquery
$('#file').change(function()
{
var iframe = $('<iframe name="postiframe" id="postiframe" style="display:none" />');
$("body").append(iframe);
var form = $('#form');
form.attr("action", "../hub.php?handler=add_item");
form.attr("method", "post");
form.attr("enctype", "multipart/form-data");
form.attr("encoding", "multipart/form-data");
form.attr("target", "postiframe");
form.attr("file", $('#file').val());
form.submit();
$("#postiframe").load(function()
{
iframeContents=$("#postiframe")[0].contentWindow.document.body.innerHTML;
console.log('added : '+iframeContents);
});
});
The above code outputs nothing other than the "added :" portion. Any help is greatly appreciated :)
You have to echo/print the filename or path from the server after the upload is complete (preferably in text/HTML as you're posting to an iframe) so you can obtain it with Javascript as in your question's code.
iframeContents=$("#postiframe")[0].contentWindow.document.body.innerHTML;
console.log('added : '+iframeContents);
You may as well code a new JS request to fetch the uploaded images through Ajax to a new PHP (echoing JSON for example), but it's unneeded if you want to get just the uploaded file in that form submit.
You can pass some string data from iframe to main window using window.name technique.
Short example of using:
Iframe:
//doing your stuff, when finished store what you need in window.name property
window.name = '{"key1":"mydata1","key2":"mydata2"}'
window.location.href='about:blank';
Main window:
$(iframe).bind('load',function(){
//triggered every time iframe's location is changed
var iframe_data = this.contentWindow.name;
if(!iframe_data.length) {
//it's a first time iframe loaded
return;
}
else{
//iframe location is changed, we're expecting to receive some data
$(this).unbind('load');
console.log($.parseJSON(iframe_data));
//{"key1":"mydata1","key2":"mydata2"}
}
})
It should work even if the iframe placed at another origin (domain).
I didn't tested this code specifically, but it should work, i copypasted it from one of my projects