Sorry, if not understandable on some points, I'm trying my best:
I'm trying to fix my little AJAX bug, which contains a file upload with ajaxSubmit. I want to show a progressbar but when first clicking on the submit button, the OnProgress event does not work, although the consolelog shows the percentage of the completion.
After the first upload, I'm choosing another file WITHOUT refreshing the page. From this time on, the progressbar works perfectly.
What problem does cause the OnProgress event not to start on the first time?
HTML:
<form method="post" action="<?php echo URL; ?>album/uploadImage/<?php echo $this->album->id; ?>" enctype="multipart/form-data" id="form_upload">
<input id="imgUpload" name="file_upload" type="file" required />
<div class="progress success radius">
<span class="meter"></span>
</div>
<input type="submit" value="Bild hochladen" id="submitupload" />
</form>
jQuery, in connection with the jQuery Form plugin: (Please check the comments on the function OnProgress!)
var progressbar = $('.meter');
var completed = '0%';
var options = {
target: 'body',
beforeSubmit: beforeSubmit,
uploadProgress: OnProgress,
success: afterSuccess,
resetForm: true
};
$(document).ready(function() {
$('#form_upload').submit(function() {
$(this).ajaxSubmit(options);
return false; // Verhindert das Neuladen der Seite!
});
});
function OnProgress(event, position, total, percentComplete) {
console.log("OnProgress called: " + percentComplete + "%");
progressbar.width(percentComplete + "%");
// This line is only working AFTER the first time.
// When clicking on the submit button the first time,
// the progressbar does not increase.
}
function afterSuccess() {
console.log("AfterSuccess called.");
}
function beforeSubmit() {
console.log("BeforeSubmit called.");
}
In addition after the first time I uploaded a picture, other jQuery initializations are not working anymore. I'm using the Foundation 5 Framework and initialize it with
<script>
$(document).foundation();
</script>
But after the first picture, some events like the Alert-Box closing link are not working anymore.
After 2 days, I found the problem.
var progressbar = $('.meter');
var completed = '0%';
both were not loaded, this means, they're not in the
$(document).ready(function () { ... });
bracket.
So the progressbar and the value of "completed" were initialized on the second upload, when the body was refreshed.
This also solved the problem with the success alert-box, which showed up after the upload. Finally, I can close the alert-box with a simple click on its cross.
Related
I'd like to display the #LoadingDiv while checkCoupon is firing, and have it disappear when it finishes, to show the function is in progress. checkCoupon is triggered by a button click (not displayed).
I've tried a variety of things including creating another function to include in onclick event, I've put this in different parts of the ajax call, and tried altering the CSS in different ways. It's still not working.
Any idea how to get this functionality and have this display properly at the beginning of the call starts?
function checkCoupon() {
var coupon = document.getElementById('couponCode').value;
var coupon_v = false;
$('#LoadingDiv').css('display', 'block');
$.ajax({
type: 'post',
url: 'coupon.php',
async: false,
data: {
'coupon': coupon
},
success: function(data) {
if (data != "empty") {
coupon_v = data;
}
}
})
}
<div id="LoadingDiv" style="display:none;">One Moment Please...<br />
<img src="images/progressbar.gif" class="displayed" alt="" />
</div>
You can hide the div on ajax complete function which is called when the request finishes (after the success or error callbacks are executed):
complete: function(){
$('#LoadingDiv').hide();
}
You can make use of jQuery's beforeSend and complete methods to address states before and after the call:
function checkCoupon() {
var coupon = document.querySelector('#couponCode').value;
var coupon_v = false;
let $loading = $('#LoadingDiv');
$.ajax({
type: 'post',
url: '.', //coupon.php
async: false,
data: {
'coupon': coupon
},
beforeSend: function() {
$loading.removeClass('hide')
},
success: function(data) {
if (data != "empty") {
coupon_v = data;
}
},
complete: function() {
// timeout only used for demo effect
window.setTimeout(function() {
$loading.addClass('hide')
}, 1500)
}
})
}
.hide {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="LoadingDiv" class="hide">One Moment Please...<br />
<img src="images/progressbar.gif" class="displayed" alt="" />
</div>
<input type="hidden" id="couponCode" value="3" />
<button onclick="checkCoupon()">Click</button>
I had the same issue. I know this is an older question by now, but obviously still relevant as I ran into the same conundrum.
I would call the showLoadingOverlay() method which would make the loading div visible, then run the function I wanted to run and then hide the loading overlay, but the overlay would never show. I finally found that the issue was that the function I was performing after showing the loading overlay was happening too quickly and it would pause the process of showing the overlay until it was done and then the hide function on the overlay was being called too quickly afterwards when the show method was able to resume. This is why it appeared that nothing was happening at all.
So, you need to delay the function you are trying to call (I used the setTimeout() method). The 400 in the setTimeout() method is 400 miliseconds that will be delayed before performing the processFunction method. Here is a generic way to accomplish your goal:
Javascript:
/******************************************************************************************
* Toggle loading overlay.
* ***************************************************************************************/
/**
* Toggle the loading overlay in order to prevent the user from performing any actions.
* The processFunction must call the endLoadOverlay method once it is finished.
* #param {any} processFunction The process to perform while the loading screen is active.
* This method must call the endLoadOverlay method once it is done.
*/
function startLoadOverlay(processFunction) {
$('#overlay').css('display', '');
setTimeout(processFunction, 400);
}
/**
* Ends the loading overlay.
* */
function endLoadOverlay() {
$('#overlay').css('display', 'none');
}
/******************************************************************************************
* End of toggle loading overlay.
* ***************************************************************************************/
Then when you call the startLoadOverlay() method pass the method that you want to accomplish through it. In my example I'm having a button click event call the overlay method:
HTML:
<button id="btnDoAction" type="button" onclick="startLoadOverlay(myFunctionToAccomplish);">Accomplish Something</button>
Remember, myFunctionToAccomplish() is the method that I want performed while the overlay is visible. NOTE: The method that you pass to the startLoadOverlay() method must call the endLoadOverlay() method after it is done processing in order to hide the loading overlay. So:
Javascript
function myFunctionToAccomplish() {
// Perform functionality.
//TODO: Add whatever functionality here.
// Once I'm done I need to call the endLoadOverlay() method in order to hide the loading overlay.
endLoadOverlay();
}
In case you are curious about my $('#overlay') element. The idea is basically from here: https://www.w3schools.com/howto/howto_css_overlay.asp
I am using an ajax call to display a show method content for different products in popovers in my page.
I use the following code:
function details_in_popup(link, div_id){
$.ajax({
url: link,
success: function(response){
$('#'+div_id).html(response);
}
});
return '<div id="'+ div_id +'">Loading...</div>';
}
$(function () {
$('[data-toggle="popover"]').popover({
"html": true,
"title": '<span class="text-info"><strong>title</strong></span>'+
'<button type="button" id="close" class="close" >× </button>',
"content": function(){
var div_id = "tmp-id-" + $.now();
return details_in_popup($(this).data('url'), div_id);
}
}).on('shown.bs.popover', function(e){
var popover = jQuery(this);
$('body').on('click','.close', function(e){
popover.popover('hide');
});
});
});
The problem that i am encountering is that the first time i open a popover, the content get filled properly, the second time, i get title duplicates in the popover, then the third time, content from the first popover and the second one get all mixed up.
It's like if the previous popovers are never cleaned-up and get accumulated each time i open a new popover...
Is there something obvious in the code that might be creating this problem ?
Thanks!
reset the div on ajax success with
$('#'+div_id).text('');
than append the response.
I have a button with which i want to use the "upclick"-plugin for uploading files
<script type="text/javascript" src="~/Scripts/upclick-min.js"></script>
<input type="button" id="uploader" value="Upload" >
<script type="text/javascript">
var uploader = document.getElementById('uploader');
upclick(
{
element: uploader,
action: '/path_to/you_server_script.php',
onstart:
function(filename)
{
alert('Start upload: '+filename);
},
oncomplete:
function(response_data)
{
alert(response_data);
}
});
Now the button works in itself and opens the "open file"-dialogue, but i cannot seem to fire the "click"-event on it programmatically. Ive tried all different ways of writing it syntax-wise:
if (ui.draggable.hasClass('ui-dragdrop-picElement')) {
//$("uploader").trigger("click");
//$("uploader").click();
//$('uploader').click();
//$('#uploader').click();
//$("#uploader").click();
//$("#uploader").trigger("click");
//$('button#uploader').trigger('click');
$('#uploader').trigger('click');
alert("w00t");
}
and so on - any idea why it wont fire - i get the alert message!
$("uploader")...
This isn't valid. There is no <uploader> element.
Your last .click uses the correct selector, but you'll want to use this with the .trigger() event:
$("#uploader").trigger("click");
You'll probably benefit a lot from going through the official jQuery tutorial: http://try.jquery.com.
I have a upload function in my app. this function uploads an excel file and the parses it and copies the data the database. The actual upload doesn't tale that long but the parsing does. I would like to have a progress bar so i could give the user some fees back.
I am not quite sure how to go about doing this. The stuff I have found online hasn't been that helpful.
This What I have so far ..
My View:
<div>
#using (Html.BeginForm("Upload", "Administrator", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.ValidationSummary(true, "File upload was unsuccessful. Please correct the errors and try again.")
<input type="file" name="FileUpload1" />
<input type="submit" name="Submit" id="Submit" value="Upload" onclick=" return startUpload();"/>
}
</div>
<input type="button" value="test" onclick=" return startUpload();"/>
<div id="loadingScreen" title="Loading...">
<div id="progressbar"></div>
</div>
My Scripts:
<script type="text/javascript">
$(document).ready(function() {
// create the loading window and set autoOpen to false
$("#loadingScreen").dialog({
autoOpen: false, // set this to false so we can manually open it
dialogClass: "loadingScreenWindow",
closeOnEscape: false,
draggable: false,
minWidth: 30,
minHeight: 30,
modal: true,
buttons: {},
resizable: false,
open: function(event, ui) {
$(".ui-dialog-titlebar-close").hide();
},
}); // end of dialog
});
$(function () {
//Progressbar initialization
$("#progressbar").progressbar({ value: 0 });
});
function startUpload() {
if (confirm("Doing this will override any previous data. Are you sure you want to proceed?")) {
$("#loadingScreen").dialog('open');
startProgressBar();
return true;
} else {
return false;
}
}
function startProgressBar() {
//Making sure that progress indicate 0
$("#progressbar").progressbar('value', 0);
//Setting the timer
setTimeout("updateProgressbar()", 500)
};
function updateProgressbar() {
$.get('#Url.Action("UploadProgress")', function (data) {
alert(data);
//Updating progress
$("#progressbar").progressbar('value', data);
setTimeout("updateProgressbar()", 500)
});
};
</script>
What this does is it brings up the modal dialog box with the the progressbar but the bar doesnt get updated.
however if I have the following button
<input type="button" value="test" onclick=" return startUpload();"/>
this brings up the modal box and updates the bar as well.
What I can understand from this is that since the upload button is doing a post I cant to a get till is finishes ...???
I am not that comfortable with JavaScript so if I am doing something really horrible please let me know ...
This may be overkill but you can use SignalR. This is a library specifically for real-time communication between the server and client.
You would upload the file using a regular action, then render a SignalR-page showing the parsing progress (the server sends the client regular updates as it parses).
See this article for a walk-through specifically about a progress bar.
There's nice and easy progress bar, it's just HTML+CSS+JavaScript. You have to call a JavaScript function to refresh the slider. Find description here: progress bar
May this will help you..
Simply call the fadeIn() method on your submit click.
$('Submit').click(function () {<br />
$("#loadingScreen").fadeIn();<br />
});
I have a slideshow which runs automatically and you can skip to an image by clicking on a button.
It works fine if you click one of the buttons when the image is static, but if you click while the fade functions are running it will run the functions twice which creates some kind of loop which eventually grinds the browser to a stand still!
I know I need to add some kind of "isRunning" flag, but I don't know where.
Here's a link to a jsfiddle - http://jsfiddle.net/N6F55/8/
And code also below...
javascript:
$(document).ready(function() {
var images=new Array();
var locationToRevealCount=6;
var nextimage=2;
var t;
var doubleclick;
addIcons();
function addIcons() {
while (locationToRevealCount>0) {
$("#extraImageButtons").append('<img class="galleryButtons" src="http://www.steveszone.co.uk/images/button_sets/pink_square_button1n.png" alt="'+locationToRevealCount+'" />');
images[locationToRevealCount]='http://www.tombrennand.net/'+locationToRevealCount+'a.jpg';
locationToRevealCount--;
};
$('.homeLeadContent').prepend('<img class="backgroundImage" src="http://www.tombrennand.net/1a.jpg" />');
$("#extraImageButtons img.galleryButtons[alt*='1']").attr("src","http://www.steveszone.co.uk/images/button_sets/black_square_button1n.png");
runSlides();
}
function runSlides() {
clearTimeout(t);
t = setTimeout(doSlideshow,3000);
}
function doSlideshow() {
if($('.backgroundImage').length!=0)
$('.backgroundImage').fadeOut(500,function() {
$('.backgroundImage').remove();
slideshowFadeIn();
});
else
slideshowFadeIn();
}
function slideshowFadeIn() {
if(nextimage>=images.length)
nextimage=1;
$("#extraImageButtons img.galleryButtons").attr("src","http://www.steveszone.co.uk/images/button_sets/pink_square_button1n.png");
$("#extraImageButtons img.galleryButtons[alt*='"+nextimage+"']").attr("src","http://www.steveszone.co.uk/images/button_sets/black_square_button1n.png");
$('.homeLeadContent').prepend($('<img class="backgroundImage" src="'+images[nextimage]+'" style="display:none;">').fadeIn(500,function() {
nextimage++;
runSlides();
}));
}
$("#extraImageButtons img.galleryButtons").live('click', function() {
nextimage=$(this).attr("alt");
$("#extraImageButtons img.galleryButtons").attr("src","http://www.steveszone.co.uk/images/button_sets/pink_square_button1n.png");
$(this).attr("src","http://www.steveszone.co.uk/images/button_sets/black_square_button1n.png");
clearTimeout(t);
doSlideshow();
});
});
html:
<div class="homeLeadContent" style="width:965px;">
</div>
<div id="extraImageButtons"></div>
Two changes make it work better for me:
Down in the "extra image buttons" handler, you call "clearInterval()" but that should be changed to "clearTimeout()".
I added another call to "clearTimeout(t)" in the "runSlides()" function right before it sets up another timeout.
Clicking on the big "CLICK ME" button might still do weird things.
edit — well here is my fork of the original jsfiddle and I think it's doing the right thing. In addition to calling "clearTimeout()" properly, I also changed the code in "doSlideshow()" so that it empties out the content <div> before adding another image.