I'm looking to use the bootstrap progress bar with a Razor ajax form but I'm unsure how to proceed. Whenever I search for the topic, I get results for jquery ajax like this one, but not for a Razor ajax form. My Razor form is as follows:
#using (Ajax.BeginForm("MyAction", null,
new AjaxOptions
{
HttpMethod = "POST",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "myDiv"
}, new { #class = "form-inline" }))
{
...
}
Here is with jquery ajax.
$.ajax({
url:"",
async: true,
xhr: function () {
var xhr = new window.XMLHttpRequest();
//Upload Progress
xhr.upload.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = (evt.loaded / evt.total) * 100; $('div.progress > div.progress-bar').css({ "width": percentComplete + "%" }); } }, false);
//Download progress
xhr.addEventListener("progress", function (evt)
{
if (evt.lengthComputable)
{ var percentComplete = (evt.loaded / evt.total) *100;
$("div.progress > div.progress-bar").css({ "width": percentComplete + "%" }); } },
false);
return xhr;
},
Since Razor doesn't have an ajax option xhr, how would I go about accomplishing this behavior?
Related
i saw many examples - all looked pretty much the same to - make a progress bar (while uploading a file - until it finishes uploading)
so i tried this code -
$.ajax({
xhr: function () {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
console.log(percentComplete);
$('.progress').css({
width: percentComplete * 100 + '%'
});
if (percentComplete === 1) {
$('.progress').addClass('hide');
}
}
}, false);
xhr.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
console.log(percentComplete);
$('.progress').css({
width: percentComplete * 100 + '%'
});
}
}, false);
return xhr;
},
type: 'POST',
url: "/echo/html",
data: data,
success: function (data) {}
});
ignore the url and the data - the example is on the xhr part
so when i tried to use this i saw that many people say that it no longer supported with jQuery 1.9.3+.
anybody has an idea how i can do it?
I know there are a few post about this but they dont cover what i need to achieve.
I'm trying to get the youtubelike loading bar to work properly.
And i found this :
var data = [];
for (var i = 0; i < 100000; i++) {
var tmp = [];
for (var i = 0; i < 100000; i++) {
tmp[i] = 'hue';
}
data[i] = tmp;
};
xhr: function () {
var xhr = new window.XMLHttpRequest();
var percentComplete = 0; <--------------------------added this
$('.progress').removeClass('hide');<----------------and this
xhr.upload.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
console.log(percentComplete);
$('.progress').css({
width: percentComplete * 100 + '%'
});
if (percentComplete === 1) {
$('.progress').addClass('hide');
}
}
}, false);
xhr.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
console.log(percentComplete);
$('.progress').css({
width: percentComplete * 100 + '%'
});
}
}, false);
return xhr;
}
I have added 2 lines because it would only work once as the hidden value was not being removed after the completion. Also put the width back to 0. I also like the fact that it seams to be calculating the real percentage of the event.
This is working great. Howerver, i want to turn this into a function that can be called for all my ajax call like this:
$(document).ready(function () {
$("a").on("click", function (event) {
event.preventDefault();
var id = ($(this).attr("id"));
var container = ($(this).attr("data-container"));
var link = ($(this).attr("href"));
var text = ($(this).text());
var html = ($(this).html());
MY_LOADING_BAR_FUNCTION();<-----------------------------------Here i guess?
$.ajax({
url: 'ajax-php.php',
type: 'post',
data: { 'action': 'click', 'id': id, 'text': text, 'link': link, 'html': html },
success: function (data, status) {
if (container == '#formbox') {
$("#screen").addClass("visible");
}
$(container).html(data);
},
error: function (xhr, desc, err) {
console.log(xhr);
console.log("Details: " + desc + "\nError:" + err);
}
}); // end ajax call
}); // end on click
}); // en document ready
But i also ran across the Ajax setup that looks like this.
$.ajaxSetup({
beforeSend: function() {
},
complete : function() {
}
});
Right now i got it to work by putting the entire code of the xhr: function () inside my ajax call. But i dont want to do it every time.
So these are the 2 options i have found that could work but i cant get them to work the way i want. I try to make a MY_LOADING_BAR_FUNCTION() but i'm getting a deprecated error.
Can anyone tell me how to make this work please.
Thank you everyone!
It's late to reply, but its worth to share some knowledge, so others may get help from it.
You can extend jQuery AJAX XHR object as below.
jQuery.ajaxSettings.xhr = function ()
{
var xhr = new window.XMLHttpRequest();
//Upload progress
xhr.upload.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
//Do something with upload progress
console.log('percent uploaded: ' + (percentComplete * 100));
}
}, false);
//Download progress
xhr.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
//Do something with download progress
console.log('percent downloaded: ' + (percentComplete * 100));
}
}, false);
return xhr;
}
Google Chrome's console is telling me
Uncaught TypeError: Illegal Invocation
when the following function is invoked
$('#txtUploadFile').on('change', function (e) {
var files = e.target.files;
if (files.length > 0) {
if (window.FormData !== undefined) {
var data = new FormData();
for (var x = 0; x < files.length; x++) {
data.append("file" + x, files[x]);
}
$.ajax({
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total * 100;
console.log("percentComplete = " + percentComplete);
}
else
{
console.log("lengthComputable evaluated to false;")
}
}, false);
xhr.addEventListener("progress", function(evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total * 100;
console.log("percentComplete = " + percentComplete);
}
else
{
console.log("lengthComputable evaluated to false;")
}
}, false);
return xhr;
},
type: 'POST',
url: '#Url.Action("upload","FileUploadAsync")',
data: data,
success: function(data){
console.log("success!");
}
});
} else {
alert("This browser doesn't support HTML5 file uploads!");
}
}
});
I've looked through StackOverflow posts on this issue and none of the causes relate to anything I can see in mine. I'm not sure if it matters, but I can post the HTML and the controller if that could be part of the problem.
You're missing two options for the $.ajax call, these
contentType: false,
processData: false,
Making it like this
$.ajax({
xhr: function () {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total * 100;
console.log("percentComplete = " + percentComplete);
} else {
console.log("lengthComputable evaluated to false;")
}
}, false);
xhr.addEventListener("progress", function (evt) {
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total * 100;
console.log("percentComplete = " + percentComplete);
} else {
console.log("lengthComputable evaluated to false;")
}
}, false);
return xhr;
},
type: 'POST',
url: '#Url.Action("upload","FileUploadAsync")',
data: data,
contentType: false,
processData: false,
success: function (data) {
console.log("success!");
}
});
if you let jQuery process the files internally it throws an Illegal invocation error.
I have a script that sends a base64 video to the server via backbone/ajax:
video = new AccountVideo();
video.set({video: imageFile});
this.collection.create(video, {
// wait for return status from server
wait: true,
success: function(model, response) {
App.utils.notifyEnd('Video is queued for transcoding.');
accountVideoListView.render();
},
error: function(model, xhr) {
App.utils.notifyEnd(xhr.responseJSON.message, 'error');
}
});
I am trying to find away to create an upload progress bar similar to how this works, but within backbone entirely.
var ajax = new XMLHttpRequest();
ajax.upload.addEventListener("progress", progressHandler, false);
ajax.addEventListener("load", completeHandler, false);
ajax.open("POST", "/api/accounts/videos");
ajax.send(imageFile);
function progressHandler(event){
var percent = (event.loaded / event.total) * 100;
console.log(percent);
} function completeHandler(event){
}
I tried:
var self = this;
xhr: function() {
var xhr = $.ajaxSettings.xhr();
xhr.onprogress = self.handleProgress;
return xhr;
}
handleProgress: function(evt){
var percentComplete = 0;
if (evt.lengthComputable) {
percentComplete = evt.loaded / evt.total;
}
console.log(Math.round(percentComplete * 100)+"%");
}
But it would only show a 0% after the video finished. I think I am close, just need a pointer. Thanks!
Ok, so I looked around and found out a little more about what's going on with the xhr: function.
Here is what is working
// add image model to collection
this.collection.create(video, {
// wait for return status from server
wait: true,
success: function(model, response) {
App.utils.notifyEnd('Video is queued for transcoding.');
accountVideoListView.render();
},
error: function(model, xhr) {
App.utils.notifyEnd(xhr.responseJSON.message, 'error');
},
xhr: function() {
myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){
myXhr.upload.addEventListener('progress',showProgress, false);
} else {
console.log("Upload progress is not supported.");
}
return myXhr;
}
});
function showProgress(evt) {
if (evt.lengthComputable) {
var percentComplete = (evt.loaded / evt.total) * 100;
console.log(percentComplete);
}
}
I'm trying to have a progress bar until ajax request has ended (this is text field + a canvas image captured from laptop webcam). But there is no progress on my bar... It appears then, when it finished, it disappear, but no visual progression on...
$("#FormSubmitPhotoCapture").click(function (e) {
e.preventDefault();
if($("#form_titre_photo_capture").val()==="")
{
alert("Veuillez saisir un titre");
return false;
}
var canvas = document.getElementById('canvascapt');
var context = canvas.getContext('2d');
var dataURL = canvas.toDataURL();
document.getElementById('imagecaptimg').src = dataURL;
var myData = {titre : $("#form_titre_photo_capture").val(), image_capture : "" + dataURL + ""}
jQuery.ajax({
beforeSend:function(x){
$('#progression').html("<progress id='bar' value='0' max='100'></progress>").show();
},
type: "POST",
url: "captureimg",
dataType:"text",
data:myData,
success:function(response){
$('#bar').val(100);
$("#responds").before(response);
$("#form_titre_photo_capture").val('');
$("#webcam_photo_capture").empty();
$('#FormSubmitPhotoCapture').hide();
},
complete: function() {
$('#bar').hide();
}
});
});
Any idea please?
You're not listening for progress events. This should work:
$.ajax({
xhr: function()
{
var xhr = new window.XMLHttpRequest();
//Upload progress
xhr.upload.addEventListener("progress", function(evt){
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
//Do something with upload progress
console.log(percentComplete);
}
}, false);
//Download progress
xhr.addEventListener("progress", function(evt){
if (evt.lengthComputable) {
var percentComplete = evt.loaded / evt.total;
//Do something with download progress
console.log(percentComplete);
}
}, false);
return xhr;
},
type: 'POST',
url: "/",
data: {},
success: function(data){
//Do something success-ish
}
});