Im uploading video and image files with progress bar using jquery ajax. Im using server side form validation and check duplicate entry. My issue is validation error message show after progress bar becomes complete. I want something like this...
if form validation is correct
then show progress bar
else if form validation is not correct
then only show error message of form validation
else if duplicate entry
then only show error message of duplicate entry
this is my js code:
$.ajax({
url: ajaxUrl,
type: 'POST',
dataType: 'json',
processData: false,
contentType: false,
async: true,
data: formData,
xhr: function () {
//upload Progress
var xhr = $.ajaxSettings.xhr();
if (xhr.upload) {
xhr.upload.addEventListener('progress', function (event) {
var percent = 0;
var position = event.loaded || event.position;
var total = event.total;
if (event.lengthComputable) {
percent = Math.ceil(position / total * 100);
}
var temp = event.loaded/event.total*100;
//update progressbar
$('div#upload-progress').text(percent + "%");
$('div#upload-progress').css("width", + temp + "%");
}, true);
}
return xhr;
},
complete: function(xhr) {
if(xhr.responseText) {
//console.log(xhr);
}
},
success: function(data, status){
if (data.hasOwnProperty('form-error')) {
$.each(data['form-error'], function (key, value) {
$("span#span_" + key).text(value);
})
} else {
// Form validation is correct
}
},
error : function(xhr, textStatus, errorThrown) {
var data = xhr.responseText;
myWindow = window.open("data:text/html," + encodeURIComponent(data), "parent", "width=1000, height=600");
myWindow.focus();
}
});
Can anyone give me any suggestion to how to do this?
If you're using the server to validate the file, that means that the file will have to be uploaded first before you can validate it, hence why you see the progress bar first. If you only want to check for duplicates (based on filename, size etc.), you need 2 ajax requests:
Send only the filename & size and validate it.
If valid, upload the file. (and validate again, of course)
Just my 2 cents.
I did made a AJAX file upload with a progress bar, you might want to take a look? I guess?
https://github.com/felixfong227/fileupload/blob/master/static/js/index.js
Related
I have an ajax request, whereby I am installing a magento shop automatically, and when the process is done, it would redirect the user to the newly created shop. Here are my codes:
function postSuccessFormData() {
var targetUrl = '/index.php/install/wizard/successPost';
jQuery('.form-button').addClass('loading');
setInterval(installStatus(),4000);
jQuery.ajax({
url: targetUrl,
global: false,
type: 'POST',
data: ({
finish: 1,
password_key: jQuery('#password_key').val()
}),
async: true,
dataType: 'json',
error: function() {
alert("An error has occurred. Please try again.");
},
success: function(data) {
window.location.href = '/';
}
});
function installStatus() {
var installerUpdatesUrl = '/index.php/install/wizard/installerStatus';
//showProgressBar();
jQuery.ajax({
url: installerUpdatesUrl,
// global: false,
type: 'GET',
async: true,
dataType: 'json',
error: function (data) {
// alert(data.result);
},
success: function (data) {
handle data.result
var dataKeys = Object.keys(data);
var lastElementKey = dataKeys[dataKeys.length - 1];
var lastMessage = data[lastElementKey]['message'];
if(data[lastElementKey]['progress'] == '') {
updateProgressBar(data[dataKeys[dataKeys.length - 2]]['progress'],100);
}
setting message
jQuery("#message").html(lastMessage);
if (data[lastElementKey]['state'] == 'Failure') {
var stepStr = lastElementKey.split('_');
var stepString = stepStr[0].toUpperCase() + ' ' + stepStr[1] + ':';
alert(stepString + "\n" + data[lastElementKey]['message']);
//hideProgressBar();
jQuery('.form-button').removeClass('loading');
return false;
} else if (data[lastElementKey]['state'] == 'Finish') {
alert(data[lastElementKey]['message']);
//hideProgressBar();
jQuery('.form-button').removeClass('loading');
//window.location.href = '/';
} else {
// installStatus();
}
},
complete: function () {
installStatus();
jQuery('.form-button').removeClass('loading');
}
});
}
The way this is done:
After every 4 seconds the function installStatus is run, which will output the current progress in JSON format. My problem is, this function needs to be executed simultaneously with the function post().
This is not happening, the installStatus is only run after the first function has been completed.
What is wrong?
You are executing installStatus when you define it. So this:
setInterval(installStatus(),4000);
needs to be
setInterval(installStatus, 4000);
The new XMLHttpRequest has a nice progress event you can listen to show the user the upload progress.
Here's the spec with a nice demo: https://developer.mozilla.org/en/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Monitoring_progress
Initially you should call installStatus() only once and then inside the method inside ajax success you should update the procent in the progress bar and call it recursively the same method. On the server side you can save the current procent in a cookie and with every recursive call you can update the cookie and return the procent.
I have an image upload feature that works like this:
$('.update-insertimage-form').submit(function() {
$(".submit-newupdate-btn").addClass('disabled');
var rootAsset = $('.rootAsset').html();
var formData = new FormData($('.update-insertimage-form')[0]);
$.ajax({
url: rootAsset+'saveUploadedImage',
type: 'post',
cache: false,
dataType: 'json',
data: formData,
processData: false,
contentType: false,
beforeSend: function() {
$(".form-control-addupdate").append('<div class="uploading-overlay">Uploading Image...</div>');
$(".uploading-overlay").fadeIn();
},
success: function(data) {
$(".submit-newupdate-btn").removeClass('disabled');
if(data.errors) {
$('.modal-body').append('<div class="alert alert-danger centre-text modal-error-message" role="alert"><strong>Error!</strong> '+ data.errors +'</div>');
} else if (data.success) {
$(".form-control-addupdate").append('<img class="temp_added_image" src="/public_html/user_uploads/build_images/'+data.name+'.jpeg"><br><br>');
$(".uploading-overlay").fadeOut(function(){
$(".uploading-overlay").remove();
});
var $t = $('.form-control-addupdate');
$t.animate({"scrollTop": $('.form-control-addupdate')[0].scrollHeight}, "slow");
}
},
error: function(xhr, textStatus, thrownError) {
alert('Something went to wrong.Please Try again later...');
}
});
return false;
});
Instead of just 'Uploading Image' I want to show the user a percentage or a loading bar etc. I have searched around but cannot find much information. My thoughts so far are tracking when the ajax call is made and then when the success call back is returned. But no idea how to generate a loading percentage etc.
I would rather use a percentage number as apposed to a loading bar, and it can be a 'fake' number just so long as it increases and finishes at 100% when the image is uploaded.
Thanks!
EDIT: Just to make it clear, I dont need a specific and real percentage. Just a way of increasing from 1 - 100% from the point the call is made to it being received.
You'll want to include the xhr option in the AJAX request and add an Event Listener to track the progress of the request:
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.addEventListener('progress', function(e) {
$('.progressbar .bar').css('width', '' + (100 * e.loaded / e.total) + '%');
$('.progresspercent').text((100 * e.loaded / e.total) + '%');
});
return xhr;
},
Where progressbar and progresspercent are elements in your HTML
I am trying to send file to server with HTML and JavaScript. The scenario like below :
user clicks some button and it shows a div pop up.
user inputs file with <input type='file'>.
user presses button.
send data to server and div pop up closes.
Note that all of these actions happen in one page. Only div pop up can be open and closed.
At first, I was trying to send data with a <form> tag, and it works fine. The problem is when I submit the form it changes the page.
So what I am trying to do is sending file data without using a form tag. I have searched web, it looks somehow impossible. Is there any alternative way to send file data in div pop up?
Thanks :D
Have you considered doing it via JQuery?
You can post the values like this without a refresh:
$('#button').on('click', function(){
$.post('/url/to/your/function', {'post': value}, function(data){
if(data !== 0) {
}
}, "json");
});
You can find more info here
Edit:
It's not possible to upload files with jQuery $.post, neverthless, with the file API and XMLHttpRequest, it's perfectly possible to upload a file in AJAX, and you can even know how much data have been uploaded yet…
$('input').change(function()
{
var fileInput = document.querySelector('#file');
var xhr = new XMLHttpRequest();
xhr.open('POST', '/upload/');
xhr.upload.onprogress = function(e)
{
/*
* values that indicate the progression
* e.loaded
* e.total
*/
};
xhr.onload = function()
{
alert('upload complete');
};
// upload success
if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 0))
{
// if your server sends a message on upload sucess,
// get it with xhr.responseText
alert(xhr.responseText);
}
var form = new FormData();
form.append('title', this.files[0].name);
form.append('pict', fileInput.files[0]);
xhr.send(form);
}
More info here
I found a trick. It works, but I am not sure it is good way or not.
As you recommended, I use jQuery and ajax.
function sendUpgradeReq(id){
var url = '/api/update.json';
var form = $("#upgradeFrm");
var data = new FormData(form[0]);
$.ajax({
type : 'post',
dataType : 'json',
url : url,
data : data,
enctype : "multipart/form-data",
cache : false,
contentType : false,
processData : false,
success : function(data) {
alert('Success!');
$('#applyPop').css('display', 'none');
},
complete : function(data) {
},
error : function(data, status, error) {
alert('Fail! :<');
e.preventDefaultEvent();
}
});
}
I thought the most important part here is new FormData(). It takes complete file information from <input type='file'>.
Thanks :D
I have image upload function in my "form" which gets uploaded via ajax. So, until image is uploading, User continues to fill rest of form. and than click on submit button which is another ajax function to submit whole form.
Problem is I have below function for image upload :-
jQuery(window).load(function(){
jQuery(':button').click(function(){
var formData = new FormData(jQuery('form')[0]);
jQuery.ajax({
url: 'upload.php', //Server script to process data
type: 'POST',
xhr: function() { // Custom XMLHttpRequest
var myXhr = jQuery.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: function(e) { $('#progress').css('display', 'block'); },
success: function(e) {
if (e != "no" && e != 'dir') {
$('#img').attr("src", e);
$('#imglinktosent').val(e);
} else if (e == 'dir') {
alert('Oops! We could not find \image\ directory or may be permission is not correct');
} else {
alert('File was not Uploaded, Kindly Upload Image with Size less than 512KB');
}
} ,
error: function(e) { alert('error' + e.message); } ,
data: formData,
//Options to tell jQuery not to process data or worry about content-type.
cache: false,
contentType: false,
processData: false
});
});
function progressHandlingFunction(e){
if(e.lengthComputable){
$('progress').attr({value:e.loaded,max:e.total});
}
}
});//]]>
It was hindering my complete form submission, therefore i changed it into Below function.
function uploadimage(){
jQuery(':button').click(function(){
var formData = jQuery('#myfile').val();
jQuery.ajax({
url: 'upload.php', //Server script to process data
type: 'POST',
xhr: function() { // Custom XMLHttpRequest
var myXhr = jQuery.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: function(e) { $('#progress').css('display', 'block'); },
success: function(e) {
if (e != "no" && e != 'dir') {
$('#img').attr("src", e);
$('#imglinktosent').val(e);
} else if (e == 'dir') {
alert('Oops! We could not find \image\ directory or may be permission is not correct');
} else {
alert('File was not Uploaded, Kindly Upload Image with Size less than 512KB');
}
} ,
error: function(e) { alert('error' + e.message); } ,
data: formData,
//Options to tell jQuery not to process data or worry about content-type.
cache: false,
contentType: false,
processData: false
});
});
function progressHandlingFunction(e){
if(e.lengthComputable){
$('progress').attr({value:e.loaded,max:e.total});
}
}
}
So, that whenever user clicks on "upload image" button. Image will get uploaded by "uploadimage()" function set on "button" with event "onclick".
But PHP was giving error with "undefined index myfile" in upload.php
After searching for a while, i found, There was "request payload" and no formdata option in header.
After searching more in stackoverflow, i found i have to specify this too :
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
as if you would have noticed at line 30, I am sending direct formData
data: formData,
//Options to tell jQuery not to process data or worry about content-type.
**
But I am unsure where should i specify
**
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
in my uploadimage() function to work.
Ajax doesn't support binary file transfers by default. I think it is more easy to base-64 encode your image and just post the data string to the server. You can use a html5 canvas element to get a base-64 encoded string from your image canvas.toDataURL(); . Server side you'll need to decode this string with base64_decode($yourimagedatastring);
This question already has answers here:
Uploading both data and files in one form using Ajax?
(13 answers)
Closed 9 years ago.
I am currently POSTING my form through AJAX with the following code:
$(document).ready(function(){
$("form#createForm").submit(function() { // loginForm is submitted
$("form#createForm input#createForm_submit").attr('disabled','disabled');
tinyMCE.triggerSave();
$.ajax({
type: "POST",
dataType: "json",
url: "perform", // URL of the Perl script
data: $("#createForm").serialize(),
// script call was successful
// data contains the JSON values returned by the Perl script
success: function(data){
$('div.form-group').each(function(){
$(this).removeClass('has-error');
});
if (data.error) { // script returned error
var myList = $('ul.msg-list').empty();
$.each(data.msg, function(key,item) {
$("div."+key).addClass('has-error');
$('<li>').text(item.errtxt).appendTo(myList);
});
$('div#create_createresult').html('some error').html(myList);
$('div#create_createresult').addClass("text-danger");
$("form#createForm input#createForm_submit").removeAttr('disabled');
} // if
else
{ // login was successful
//$('form#login_loginform').hide();
$('div#create_createresult').text(data.msg);
$('div#create_createresult').addClass("success");
} //else
} // success
}); // ajax
$('div#login_loginresult').fadeIn();
return false;
});
});
Now I want to add the posibility of uploading a picture in the same form and just implement it in this JQUERY and in the same server-side script. My only problem is, I don't know how to do it.. I have tested the above, and I find, that it doesn't pass the $_FILES-variable to my server side script.
Can anyone lead me in any direction of, what I need to do, to add the possibility of image upload with this script?
try to use this.
// grab your file object from a file input
$('#fileInput').change(function () {
sendFile(this.files[0]);
});
// can also be from a drag-from-desktop drop
$('dropZone')[0].ondrop = function (e) {
e.preventDefault();
sendFile(e.dataTransfer.files[0]);
};
function sendFile(file) {
$.ajax({
type: 'post',
url: '/targeturl?name=' + file.name,
data: file,
success: function () {
// do something
},
xhrFields: {
// add listener to XMLHTTPRequest object directly for progress (jquery doesn't have this yet)
onprogress: function (progress) {
// calculate upload progress
var percentage = Math.floor((progress.total / progress.totalSize) * 100);
// log upload progress to console
console.log('progress', percentage);
if (percentage === 100) {
console.log('DONE!');
}
}
},
processData: false,
contentType: file.type
});
}