Reputation: 1074
On one of my pages I use multiple forms, each holds specific data (so there is a form with user's first name, last name etc. there is another with user's address and so on). Each form have a "Save changes" button, and I use Ajax calls to submit data to the server. Problem is - on one of the forms, user can upload his picture, using Bootstrap file upload (so, first he selects the picture, and then clicks "Save" - only then is the file send to server), but I can't find any way to do it without reloading the page.
First I tried using hidden iframe
, but it would seem that I can't make copy my file data to the Iframe, so this is a no go.
Now I'm trying to use this:
but, once I include it in my page, Bootstrap file uploader stops working correctly, that is - every time I select a picture it automatically starts file upload. Weird part is - it happens even when there is no init code for fileuploader anywhere, just include code. I tried suggested "fixes", that is - I tried overriding the add method like this:
$('#file').fileupload({
dataType: 'json',
add: function (e, data) {
data.context = $('<button/>').text('Upload')
.appendTo(document.body)
.click(function () {
data.context = $('<p/>').text('Uploading...').replaceAll($(this));
data.submit();
});
},
done: function (e, data) {
data.context.text('Upload finished.');
}
});
But "add" is not getting hit for some reason...
What am I doing wrong here? Or is there any other way I can achieve the thing I want?
EDIT 1:
Here is the code I use for picture upload:
@using (Html.BeginForm("ProfileSavePictureData", "Animator", FormMethod.Post, new { enctype = "multipart/form-data", id = "pictureDataForm" }))
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(null, new { id = "profilePictureDataValidationSummary" })
@Html.HiddenFor(x => x.UserDataId)
@Html.HiddenFor(x => x.UserId)
<div class="form-group">
<div class="fileupload fileupload-new" data-provides="fileupload">
<input type="hidden" value="" name="" />
<div class="fileupload-new thumbnail" style="width: 200px; height: 150px;">
@if (Model == null || String.IsNullOrEmpty(Model.Picture))
{
<img src="http://www.placehold.it/200x150/EFEFEF/AAAAAA&text=no+image" alt="">
}
else
{
<img src="@Model.Picture" alt="@ViewBag.PictureNotAviableLabel" alt="">
@Html.HiddenFor(x => x.Picture)<br />
}
</div>
<div class="fileupload-preview fileupload-exists thumbnail" style="max-width: 200px;
max-height: 150px; line-height: 2px;">
</div>
<div>
<span class="btn default btn-file"><span class="fileupload-new"><i class="fa fa-paper-clip">
</i>
@ViewBag.ChoosePicture
</span><span class="fileupload-exists"><i class="fa fa-undo"></i>
@ViewBag.ChangePicture
</span>
<input type="file" class="default" name="file" />
</span><a href="#" class="btn red fileupload-exists" data-dismiss="fileupload"><i
class="fa fa-trash-o"></i>
@ViewBag.RemovePicture
</a>
</div>
</div>
<span class="label label-danger">
@ViewBag.InfoLabel
</span><span>
@ViewBag.PictureMinatureWarning
</span>
</div>
<div class="margin-top-10">
<button id="btnSaveChengesProfilePictureData" type="button" class="btn btn-default">@ViewBag.SaveChangesButtonLabel</button>
<input type="submit" />
</div>
}
As you can see there are two buttons at the bottom - neither does what I want...
Upvotes: 0
Views: 1877
Reputation: 61954
An example about how to create avery simple image upload form without page refresh using Bootstrap, jQuery AJAX and PHP (view live demo).
JavaScript:
function noPreview() {
$('#image-preview-div').css("display", "none");
$('#preview-img').attr('src', 'noimage');
$('upload-button').attr('disabled', '');
}
function selectImage(e) {
$('#file').css("color", "green");
$('#image-preview-div').css("display", "block");
$('#preview-img').attr('src', e.target.result);
$('#preview-img').css('max-width', '550px');
}
$(document).ready(function (e) {
var maxsize = 500 * 1024; // 500 KB
$('#max-size').html((maxsize/1024).toFixed(2));
$('#upload-image-form').on('submit', function(e) {
e.preventDefault();
$('#message').empty();
$('#loading').show();
$.ajax({
url: "upload-image.php",
type: "POST",
data: new FormData(this),
contentType: false,
cache: false,
processData: false,
success: function(data)
{
$('#loading').hide();
$('#message').html(data);
}
});
});
$('#file').change(function() {
$('#message').empty();
var file = this.files[0];
var match = ["image/jpeg", "image/png", "image/jpg"];
if ( !( (file.type == match[0]) || (file.type == match[1]) || (file.type == match[2]) ) )
{
noPreview();
$('#message').html('<div class="alert alert-warning" role="alert">Unvalid image format. Allowed formats: JPG, JPEG, PNG.</div>');
return false;
}
if ( file.size > maxsize )
{
noPreview();
$('#message').html('<div class=\"alert alert-danger\" role=\"alert\">The size of image you are attempting to upload is ' + (file.size/1024).toFixed(2) + ' KB, maximum size allowed is ' + (maxsize/1024).toFixed(2) + ' KB</div>');
return false;
}
$('#upload-button').removeAttr("disabled");
var reader = new FileReader();
reader.onload = selectImage;
reader.readAsDataURL(this.files[0]);
});
});
PHP:
<?php
session_start();
if ( isset($_FILES["file"]["type"]) )
{
$max_size = 500 * 1024; // 500 KB
$destination_directory = "upload/";
$validextensions = array("jpeg", "jpg", "png");
$temporary = explode(".", $_FILES["file"]["name"]);
$file_extension = end($temporary);
// We need to check for image format and size again, because client-side code can be altered
if ( (($_FILES["file"]["type"] == "image/png") ||
($_FILES["file"]["type"] == "image/jpg") ||
($_FILES["file"]["type"] == "image/jpeg")
) && in_array($file_extension, $validextensions))
{
if ( $_FILES["file"]["size"] < ($max_size) )
{
if ( $_FILES["file"]["error"] > 0 )
{
echo "<div class=\"alert alert-danger\" role=\"alert\">Error: <strong>" . $_FILES["file"]["error"] . "</strong></div>";
}
else
{
if ( file_exists($destination_directory . $_FILES["file"]["name"]) )
{
echo "<div class=\"alert alert-danger\" role=\"alert\">Error: File <strong>" . $_FILES["file"]["name"] . "</strong> already exists.</div>";
}
else
{
$sourcePath = $_FILES["file"]["tmp_name"];
$targetPath = $destination_directory . $_FILES["file"]["name"];
move_uploaded_file($sourcePath, $targetPath);
echo "<div class=\"alert alert-success\" role=\"alert\">";
echo "<p>Image uploaded successful</p>";
echo "<p>File Name: <a href=\"". $targetPath . "\"><strong>" . $targetPath . "</strong></a></p>";
echo "<p>Type: <strong>" . $_FILES["file"]["type"] . "</strong></p>";
echo "<p>Size: <strong>" . round($_FILES["file"]["size"]/1024, 2) . " kB</strong></p>";
echo "<p>Temp file: <strong>" . $_FILES["file"]["tmp_name"] . "</strong></p>";
echo "</div>";
}
}
}
else
{
echo "<div class=\"alert alert-danger\" role=\"alert\">The size of image you are attempting to upload is " . round($_FILES["file"]["size"]/1024, 2) . " KB, maximum size allowed is " . round($max_size/1024, 2) . " KB</div>";
}
}
else
{
echo "<div class=\"alert alert-danger\" role=\"alert\">Unvalid image format. Allowed formats: JPG, JPEG, PNG.</div>";
}
}
?>
Demo and source code available at:
https://github.com/ShinDarth/Bootstrap-image-upload-form
Upvotes: 0
Reputation: 1074
I finally managed to do what I wanted using this library:
https://cmlenz.github.io/jquery-iframe-transport/
And example code from above page. This library is included in jquery-file-upload as well, but that version is modified and will not work with the example from the above page.
Upvotes: 1
Reputation: 1136
I once did this little demo. It's not recent but hopefully will point you to the right direction. Basically sends the file data via Ajax to the server, the server saves the file and returns the path. That way you can do a preview of the image:
Demo: http://silviarebelo.com/demos/file_upload_ajax/
Github project: https://github.com/teknotica/file-upload-preview
Upvotes: 1