Pretext: I'm using Ajax to switch between SVG images in an interactive map.
I implemented a loader image into the Ajax requests, but every time it fires the old SVG completely disappears until the new SVG is added (causing the flicker).
The goal is to get the loader image to hover over the old content instead until the new SVG is completely loaded.
AJAX
$.ajax({
type: 'POST',
url: '/doc.php',
data: { var: var },
beforeSend:function(){
$('#container').html('<div class="loader"><img src="loader.gif"/></div>');
},
success:function(data){
$('#container').empty();
$('#container').append(data);
}
});
CSS
.loader {
height:60px; width:60px;
background-color: rgba(0,0,0,0.2);
position: absolute;
top: 25%;
left: 47%;
}
Any ideas on what I'm doing wrong?
It looks like they are removing and trying to populated at the same time. If you let (data) load then .delay(1000) or what ever number works then target that old image by id you could accomplish that. Another option is this:
complete: function(data){
$('#container').append(data).delay(1000).trigger(remove);
};
Function remove(){
$('#container').find('#fooImage').fadeToggle().remove();
};
This should be enough time for the new image to load and once that 1 second is up the function 'remove' is triggered.
Related
I am working on asp.net MVC 5. I have created 4 different types of charts in it which are viewing on same page. I am getting data from a meter at almost 15-20 seconds interval. All i want to do is to refresh my charts after each 15/20 seconds so for every new entry in DB i should not refresh my page manually. For this i have used javascript setInterval in my graph view like bellow
setInterval(function () {
$.ajax({
url: '/Home/MultiGraph',
type: "POST",
success: function (result) {
$("#c1").html(result);
}
});
alert("hello");
}, 3000);
Bellow are my divs in which i have placed my charts
<div id="c1">
<div id="container1" style="height: 400px; width:auto"></div>
<div id="container2" style="height: 400px; width:auto"></div>
<div id="container3" style="height: 400px; width:auto"></div>
<div id="container4" style="height: 400px; width:auto"></div>
</div>
At $(window).on('load', function () { } i have placed my 4 charts initialization like bellow
var chart1 = new Highcharts.Chart({//rendered to container1});
var chart2 = new Highcharts.Chart({//rendered to container2});
var chart3 = new Highcharts.Chart({//rendered to container3});
var chart4 = new Highcharts.Chart({//rendered to container4});
All the data in charts are coming in array format
So after running my page look like bellow image
After i press Ok i get bellow
I don't know why it's happening, i just want to refresh/reload the charts only but all i am getting the above results as it's refresh the whole page also on refresh i am unable to view my charts
Moreover my charts are placed in a view and this view is following the main layout i.e. else charts and search bar all my view is coming from layout
UPDATE:
Bellow is the image which is showing me the data in result
Any help would be highly appreciated
since you are using setInterval it repeats everything inside on that clause, it keeps adding HighChart object in that object.
What you can do is add beforeSend in your ajax:
$.ajax({
url: '/Home/MultiGraph',
type: "POST",
beforeSend: function (result) {
$("#c1").empty(); //empty first the div
},
success: function (result) {
$("#c1").html(result);
}
});
I have a simple div wrapper called .falling within this div I have 10 small images. I created a simple function that allows them to 'slide down' when I desire. That code is below.
JS:
function slide(){
$(".falling").delay(100).fadeIn().animate({opacity: 1, top:"300px"},'slow');}
slide();
CSS:
.falling {
width: 500px;
left: 600px;
top: 60px;
position: absolute;
display:none;
}
The problem is; 2 things. One, at the end of the 'slide down' I would like to have the .falling wrapper width to DECREASE so down to maybe 250px; because I want the illusion the images are grouping together at the end. Each img has a shared class called .imgfall I would like to use this to make the images smaller in width at the bottom as well. So, maybe max-width: 25px;
function slide(){
$(".falling").delay(100).fadeIn().animate({opacity: 1, top:"300px"},'slow');
$(".falling").css("width", "250px"); // tried this before and after slide but doesn't resize after slide but instead before, so not working!
}
slide();
By calling a function as the last parameter in jquery's animate function, you basically call an 'on complete'. See: http://api.jquery.com/animate/
var $fallingShell = $(".falling");
var animateSlides = function(){
function slide(){
$fallingShell.delay(100).fadeIn().animate({opacity: 1, top:"300px"},'slow', function(){
$fallingShell.animate({"width":"250px"}, 500);
});
}
}
And the replay needs the inline css create by the js reset. See: http://api.jquery.com/css/
I think this is everything you need to reset, but this is a best guess having not seen the code.
var resetSlides = function(){
$(".falling").css(
"width":"auto",
"opacity":"0",
"top":"0px"
);
}
So then you can tie it all together with a click or timer or something, or even call the reset at the start of animateSlides();
$('button').on('click', function(){
resetSlides();
animateSlides();
});
I have this ajax event
function save_response_with_ajax(t){
var form = $('#edit_'+t);
var div = $('#loading_'+t);
$.ajax({
url: form.attr("action"),
type: "POST",
data: form.serialize(),
cache: false,
beforeSend: function(){
form.hide();
div.show();
},
complete: function(){
div.hide();
form.show();
},
success: function (result) {
}
});
}
And everything works fine, but I want to add (if it's possible) the hability of turning the entire page (the content/body) into gray while before/complete ajax events, like if it were a modal (like this http://jqueryui.com/demos/dialog/#modal but without the dialog)
Is there a way of doing this?
Thanks in advance
Javier Q.
A way of doing this is having an overlay element which fills the entire page. If the overlay element has a semi-transparent background color, it grays out the page completely: http://jsfiddle.net/SQdP8/1/.
Give it a high z-index so that it's on top of all other elements. That way, it renders correctly, and it catches all events (and won't pass them through).
#overlay {
background-color: rgba(0, 0, 0, 0.8);
z-index: 999;
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
display: none;
}
you can try
$("body").append('<div id="overlay" style="background-color:grey;position:absolute;top:0;left:0;height:100%;width:100%;z-index:999"></div>');
then just use
$("#overlay").remove();
to get rid of it.
quick & dirty.
Try appending an overlay during the "beforeSend" function:
$("body").prepend("<div class=\"overlay\"></div>");
$(".overlay").css({
"position": "absolute",
"width": $(document).width(),
"height": $(document).height(),
"z-index": 99999,
}).fadeTo(0, 0.8);
This is the complete solution which I am using:
Following are the sections:
CSS for overlay. "fixed" is used to cover whole page content, not just screen height and widths. You can use background color or gif
Attaches to "beforeSend" event of jQuery Ajax call. Creates the overlay on demand and shows it.
Upon completion of request, it removes the overlay from DOM
CSS:
.request-overlay {
z-index: 9999;
position: fixed; /*Important to cover the screen in case of scolling content*/
left: 0;
top: 0;
width: 100%;
height: 100%;
display: block;
text-align: center;
background: rgba(200,200,200,0.5) url('../../Images/submit-ajax-loader.gif') no-repeat center; /*.gif file or just div with message etc. however you like*/
}
JavaScript:
$.ajax({
url: '/*your url*/',
beforeSend: function () {
$('body').append('<div id="requestOverlay" class="request-overlay"></div>'); /*Create overlay on demand*/
$("#requestOverlay").show();/*Show overlay*/
},
success: function (data) {
/*actions on success*/
},
error: function (jqXhr, textStatus, errorThrown) {
/*actions on error*/
complete: function () {
$("#requestOverlay").remove();/*Remove overlay*/
}
});
Use jQuery ajaxStart() to append a Div to your document. Set it to the size of your document with some form of semi-transparent document. Then remove it on ajaxStop().
var modal = $('<div>')
.dialog({ modal: true });
modal.dialog('widget').hide();
setTimeout(function() { modal.dialog('close'); }, 2000); // to close it
here is a demo: http://jsbin.com/avoyut/3/edit#javascript,html,live
don't forget to call modal.dialog('close'); to end it all!
this way you get the benefits of the actual dialog modal code, resizing, disabling, etc..
hope this helps -ck
You may want to give the user some indication that something is happening, too, not just a blank/gray screen. I would suggest some sort of loading gif, see this, for example.
Today I was looking for a solution which would work for all browsers of IE. I took the code of #pimvdb and #Ash Clarke along with his comment where he mentioned background-color: black; opacity: 0.8; may also work. For IE it will just be completely black. and came to a solution below:
$("#first-div").prepend("<div class=\"overlay-example\"></div>");
var height1 = $("#first-div").height();
var width1 = $("#first-div").width();
$(".overlay-example").css({
"background-color": "black",
"z-index": "9999999",
"position": "absolute",
"width": width1,
"height": height1,
"display": "none"
}).fadeTo(0, 0.0001);
Tested in IE8, IE9 above. Could not check for IE7. Will be glad to update my soulution in case you find it wrong. (it would help me also to update my solution :))
Thank you #pimvdb and #Ash Clarke
Demo
For whatever reason, my jquery loading overlay doesn't load at all under any circumstance even though the same code was working just days ago. Well, not the exact same code. I have been trying to get the overlay to resize with the window, and I have been trying different things, but I don't understand what I did that caused the overlay to never even show up? Here is the code that should attach to the overlay to the correct div...
function MRNSearchInternals()
{
//debugger;
var form = $("#MRNSearch");
$div = $("#TabView1");
var srlzdform = form.serialize();
var PopID = <% =PopID %>;
var options = [];
var $url = $("#target").attr("action");
$('<div id="overlay">').css({
position: 'absolute',
opacity: 0.2,
top : $div.offset().top,
left : $div.offset().left,
width : $div.offset().width,
height : $div.outerHeight(),
background: 'blue url(<%=Url.Content("~/images/ajax-loader.gif")%>) no-repeat center'
}).hide().appendTo($div);
$("#overlay").fadeIn();
$.post('<%:Url.Action("SearchByMRN", "PatientACO")%>', srlzdform, function (data)
{
DisplayDemographicSearch(data);
$("#overlay").fadeOut();
});
}
Notice how I create the div. I give it an id, and then I call it's css atribute. From there I set all the css attributes. I then attempt to call fadeIn, and fadeOut after the ajax call. Any body have any idea why this isn't working? Any help would be great.
Some More clarification
Also notice how I chose the div to overlay. I get a div id from my dom
$div = $("#TabView1");
Also, I looked the source, and I do have that particular div in there. So that is not the problem. Somehow or the other, it simply isn't showing up.
UPDATE: The DOM I get
Below is what is produced from the jquery code. It appears as though everything is being created fine. Note also, that display is set to none. That is what I would expect since I have the overlay fade out. My question is why does it never show up.
<div class="TabView" id="TabView1">
<div class="Tabs">...</Tabs>
<div class="Pages">
<div id="overlay" style="left: 114px; top: 205px; height: 452px; display: none; position: absolute; opacity: 0.2; background-image: url("/images/ajax-loader.gif"); background-attachment: scroll; background-repeat: no-repeat; background-position-x: center; background-position-y: center; background-size: auto; background-origin: padding-box; background-clip: border-box; background-color: blue;"/>
</div>
Well, the better way to create the overlay div would be
$('<div/>', {
id: 'overlay'
})
Does that solve the problem? Otherwise, the ID might not be created, or does it?
Update for the edit from your post: the "width" attribute is not set on the created overlay. What happens if that is added and set to e.g. 100px? It seems like there is something wrong with the setting of the width attribute (or the getting of the width attribute of $div).
Is this code called more than once? If so, are you removing #overlay somewhere?
Calling this code multiple times would create duplicate #overlay dom nodes which is a no-no and could explain why it doesn't work sometimes.
To remove it, change:
$("#overlay").fadeOut();
to:
$("#overlay").fadeOut('slow', function () {
$("#overlay").remove();
});
Your selector doesn't look right.
I would try:
$('#overlay').css. . . .
function MRNSearchInternals()
{
//debugger;
var form = $("#MRNSearch");
$div = $("#TabView1");
var srlzdform = form.serialize();
var PopID = <% =PopID %>;
var options = [];
var $url = $("#target").attr("action");
$('<div id="overlay">').css({
position: 'absolute',
opacity: 0.2,
top : $div.offset().top,
left : $div.offset().left,
width : $div.offset().width, //<- The problem is right here should be $div.width
height : $div.outerHeight(),
background: 'grey url(<%=Url.Content("~/images/ajax-loader.gif")%>) no-repeat center'
}).hide().appendTo($div);
$("#overlay").fadeIn();
$.post('<%:Url.Action("SearchByMRN", "PatientACO")%>', srlzdform, function (data)
{
DisplayDemographicSearch(data);
$("#overlay").fadeOut('slow', function () {
$("#overlay").remove();
});
});
}
Man. That was real hard to debugg. I wish Visual studio 2010 had better jquery debugging capability. Thankfully, the next version is supposed to be a better jquery debugger. But, the problem was the width attribute.
This function adds an overlay with the following properties to the entire browser screen,
$('a.cell').click(function() {
$('<div id = "overlay" />').appendTo('body').fadeIn("slow");
});
#overlay
{
background-color: black;
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
display: none;
z-index: 100;
opacity: 0.5;
}
And this function is supposed to remove it.
$('#overlay').click(function() {
$(this).fadeOut("slow").remove();
});
But it seems to do absolutely nothing and now my page is stuck with a black overly over it. What's wrong with the removal?
The problem is that when you're adding the click handler, there isn't any overlay, so you're adding the handler to an empty set of elements.
To fix this, use the live method to bind your handler to all elements that match #overlay, whenever they are created.
Also, fadeOut is not a blocking call, so it returns before the element finishes fading out. Therefore, you're calling remove right after the element starts fading out.
To fix this, use fadeOut's callback parameter to call remove after the animation finishes.
For example:
$('#overlay').live(function() {
$(this).fadeOut("slow", function() { $(this).remove(); });
});
Here you go. This should fix the problem and let the overlay fade out before removing it.
$('#overlay').live("click", function() {
$(this).fadeOut("slow", function() { $(this).remove() });
});
Remove should be in the callback to fadeout, like so:
$('#overlay').live('click', function() {
$(this).fadeOut("slow", function() {
$(this).remove();
});
});
Try:
$('#overlay').live('click', function() {
$(this).fadeOut("slow").remove();
});
My recommendation is to use the jquery.tools overlay plugin. Your overlay will have a trigger (usually a button or link), but you can load or clear it with a javascript command, e.g.:
js:
var config = { closeOnClick:true, mask:{opacity:0.7, color:'#333', loadSpeed:1} }
$("#myTrigger").overlay(config); // add overlay functionality
$("#myTrigger").data("overlay").load(); // make overlay appear
$("#myTrigger").data("overlay").close(); // make overlay disappear
html:
<div id="myOverlay" style="display:none;">Be sure to set width and height css.</div>
<button id="myTrigger" rel="#myOverlay">show overlay</button>