The problem:
I have a form with a button underneath it to submit (post) from data with jQuery ajax(). I want for the button to be replaced with a spinner (animated png) for the duration of server ajax call. But such a trivial task is impossible in css to do right.
What i have tried:
I have placed button and image inside a bootstrap row. Ox ajax call I have set button display to none and img display to block. But because this two are not of the same size makes the whole page flicker, breaks the positioning of other elements and so on.
Another idea was to try to place both elements on top of each other with absolute positioning. But, stupid as css is I cannot center it on the middle of the row.
Is there a way to position both elements on top of each other so I can control their visibility?
Please bear in mind that I cannot used absolute position in pixel, because this is a web page and I do not not how wide the browser will be, image can change in the future, text in the button can change in the future, all this things affect absolute size.
If there is another solution to my problem which would prevent the page from jumping up and down it would also be great.
EDIT
Link to one of fiddle experiments:
https://jsfiddle.net/ofb2qdt8/
.button {
position: relative;
margin: auto;
height: 50px;
width: 30px;
background: blue;
z-index: 1;
display: block;
}
.spinner {
position: relative;
margin: auto;
height: 30px;
width: 50px;
background:red;
z-index: 2;
}
This renders second element underneath on screen. Not on different z layer.
Experiment 2:
https://jsfiddle.net/ofb2qdt8/
.button {
position: absolute;
margin: auto;
height: 50px;
width: 30px;
background: blue;
z-index: 1;
display: block;
}
.spinner {
position: absolute;
margin: auto;
height: 30px;
width: 50px;
background:red;
z-index: 2;
}
This does not center both elements, and they are pushed to the top of the containing div. The element with less height should be centered.
Check this working demo: https://jsfiddle.net/ofb2qdt8/3/
Add in a few lines of jquery and update your css.
Position your loading div according to button div's position, width, height using jquery.
*Click the button to see loading div, and try to play the margin of the button to any pixel.
###JQUERY
$(document).ready(function () {
$('.c2').each(function () {
$(this).css({
'width': $(this).siblings('.c1').outerWidth(),
'height': $(this).siblings('.c1').outerHeight(),
'top': $(this).siblings('.c1').offset().top,
'left': $(this).siblings('.c1').offset().left
});
});
$('.c2').on('click', function () {
$(this).hide(0);
});
});
###CSS
.c1 {
margin: 100px auto;
width: 100px;
text-align: center;
padding: 5px 10px;
background: blue;
z-index: 1;
}
.c2 {
position: fixed;
text-align: center;
background: red;
z-index: 2;
cursor: pointer;
}
Rough, ready and untested:
HTML
<div>
<input type='submit' />
<img src="spinneyIMage.gif" />
</div>
CSS
div{ text-align: center; }
div img{ display: none; }
jQuery
$('submit').click(function(e){
e.preventDefault();
$(this).hide().next().show();
});
After the Ajax call completes reverse the above jQuery.
As I haven't been able to find a working solution I have reverted to my first idea which I discarded at first. Albeit with a little twist.
HTML
<div class="row>
<div id="container-button" class="col-xs-12>
<button id="button" onclick="button_OnClick(e)">submit form via ajax</button>
<img src="img/spinner.png" sytle="display: none" />
</div>
</div>
JS
function btnContact_OnClick() {
// show the soinner and hide the button
showSpinner();
$.ajax(
{
type: 'POST',
url: "someurl.com/target",
data: $("#form").serialize(),
dataType: "json",
complete: function() { hideSpinner();},
success: onAjaxSuccess,
error : onAjaxError
});
}
function hideSpinner() {
$("#spinner").hide();
$("#button").show();
// make container height non-fixed and content adjustable again
$("#container-button").height('auto');
}
function showSpinner() {
// THis is the trick !!!
// Make the container fixed height as it was before displaying spinner, so it does not change with content (spinner is not the same height as button
$("#container-button").height($("#container-button").height());
$("#button").hide();
$("#spinner").show();
}
This is not the perfect solution but the best I could make.
Drawbacks:
it is not clean, you have to use javasript to fix what is css layout
problem
it still causes a little flicker
the height of container while displaying spinner is dependant on button, this may cause clipping if spinner is too big
Related
I have a menu containing onclick calls. Then my js script catches the data and sends it to a php script for processing and returns it back to my js script which is supposed to place the results into the defined document element. Simple enough, right.
For some reason though, if I set the background color in my css the results will not show. Here are the relevant parts of my code. Can someone point out to me if there is a flaw in my code; and if not, why does this behavior happen and is there a work around.
My css...
.decade { margin-left: 150px; padding: 20px; color: green; }
.slaby { position: fixed; left: 200px; bottom: 86px; top: 50px; right:50px; color: black; padding: 20px; background-color: #ddd; border: 2px solid grey; }
My html...
<div class='tln'>
<span class='point' onclick='mes(this)' go='a' >The 70's</span>
<span class='point' onclick='mes(this)' go='b' >The 80's</span>
</div>
<div id='decade' class='decade'>
<div id='slab' class='slaby'></div>
</div>
My js...
function mes(span) {
var clam = span.getAttribute('go'); var shot = 1;
$.ajax({ url:'', type:'POST',
data:{ page: clam, shoot: shot, },
success: function(snowy){
$('#slab').html(snowy);
$('#decade').html(snowy);}});}
In my js script I am placing the results in both 'slab' and 'decade' elements just for testing purposes. Now with my css the way that it is, div(decade) is showing the results, while div(slab) is still blank.
For some reason: if I remove the background color from the div(slab) The results show here; if I add a background color to the div(decade) the results still show here.
I'm looking for a way to display the results in div(slab); as well as, having css style div(slab)'s background color. Thank you all for any help and have a great day.
Some of the other comments pointed out that #slab is "inside" of #decade so when you are doing $('#decade).html() you are replacing/removing #slab.
Use
$('#decade').append()
instead or alternatively
$('#decade').prepend()
(SOLVED) why will jquery not put results in div with background color set.
I am not sure why the query contents were not being displayed, but changing the style for div(slab) with a z-index provided the results I was looking for.
I set the z-index for div(slab) to z-index: -1; and 'voila', works perfect.
.slaby { position: fixed; left: 200px; bottom: 86px; top: 50px; right:50px; color: black; padding: 20px; z-index: -1; background-color: #ddd; border: 2px solid grey; }
I have no idea why this works because no other element inside or outside of it has a z-index set.
Thank you all for your input and effort. I hope this solution helps somebody.
I have a div "wtb_wrapper_middle" in middle of my web page.
For that div only scroll able in web page. In left and right div are not movable, it fixed in my web page.
So I want to mouse always focus on that particular div wherever my mouse clicked or mouse hover. Means when i use keyboard up or down button at that time that particular div only should be scroll.
Is there possible in JQuery.
My code is like below.
<div id="wtb_wrapper_inner">
<div id="wrapper_left">
....
....
....
</div>
<div id="wtb_wrapper_middle">
....
....
....
....
</div>
<div id="wtb_wrapper_right">
....
....
....
</div>
</div>
In from above html code "wtb_wrapper_middle" area only scrolls in my web page.
I have tried the below
window.onload = function() {
document.getElementById("wtb_wrapper_middle_inner").focus();
};
In this code is focus only on page load, but if clicked mouse in somewhere else, at that time also that middle area should be scroll. That is not working.
My Ajax callback function like below
$.ajax({
type: "POST",
url: "search.php?ajaxrequest=yes",
data: query_string
}).done(function( data ) {
$(".wtb_p_loader").remove();
$("#wtb_wm_listing").append(data);
});
I'm appending return success data into the di wtb_wm_listing which is i have placed inside of main div wtb_wrapper_middle
Anyone help me to make it success..
You can do this using css position: fixed;
The two outer divs are fixed to the screen regardless of scroll position. Then the central div scrolls regardless of where the mouse pointer is. You can use top and bottom to fix the full height of the screen, then left and right to fix each on either side.
You can still interact with content in the fixed outer divs.
And the Html is
<div class='left'>
<a href='#'>Hover to check the mouse focus and scorll</a>
</div>
<div class='center'>
//some long content
</div>
<div class='right'>
</div>
Css for doing this action.
a {
color: #000;
display: block;
font-family: arial;
margin: 10px;
text-decoration: none;
}
a:hover {
background-color: #f03055;
color: #fafafa;
}
p {
color: #fafafa;
font-family: arial;
line-height: 24px;
margin: 0 0 25px 0;
padding: 0 2%;
}
.center {
background-color: #97c;
height: 2000px;
margin: 0 25%;
width: 50%%;
}
.left {
background-color: #7c9;
bottom: 0;
left: 0;
position: fixed;
top: 0;
width: 25%;
}
.right {
background-color: #7c9;
bottom: 0;
position: fixed;
right: 0;
top: 0;
width: 25%;
}
EDIT: to filter out input elements
document.body.onkeydown = function(event){
var e = event || window.event,
target = e.target || e.srcElement;
if (target.tagName.toUpperCase() == 'INPUT') return;
document.getElementById("wtb_wrapper_middle_inner").focus();
};
this will move focus to your middle div whenever keydown event occurs.
I am working on javascript scroll. I have following html code
JSFIDDLE
<div class="wrapper">
<div class="red div current"></div>
<div class="blue div"></div>
<div class="green div"></div>
<div class="yellow div"></div>
</div>
In above code I have four div tags red, blue, green and yellow. All of them are position in following css.
html, body {
height: 100%;
}
.wrapper {
overflow: hidden;
height: 100%;
}
.div {
position: relative;
height: 100%;
}
.red {
background: red;
}
.blue {
background: blue;
}
.green {
background: green;
}
.yellow {
background: yellow;
}
In above html and css the red div tag is the current one which means user is seeing the red div tag on the screen. Now what I am trying to do is when user scroll over window once, then the next div tag i.e. blue will be animated and moved to the top and will become visible to the user whereas the red div tag will be behind the blue one. This same process goes for both green and yellow.
The problem is that when user scroll once then the div tag should animate however my current javascript code is keep reading the scroll and animating the div tags one after another. What I want is when user scroll once then scroll should be disabled until the blue div tag is animated. Then scroll should be enabled. Again when user scroll second time, the scroll should disable until the green div tag completes its animation. Same goes for yellow.
How can I achieve above?
Here is my javascript
$(window).on("scroll", function () {
var next = $('.current').next();
var height = next.outerHeight();
next.animate({top: '-=' + height}, 500, function () {
$(this).prev().removeClass('current');
$(this).addClass('current');
});
});
Please have a look on update JsFiddle
$(window).on("scroll", function () {
var next = $('.current').next();
var height = $('.current').outerHeight();
$('.current').prevAll().each(function(){
height += $(this).outerHeight();
});
next.animate({top: '-=' + height}, 500, function () {
$(this).prev().css('top','');
$(this).prev().toggleClass('current');
$(this).toggleClass('current');
});
});
The main reason your example wasn't working as expected is because you were relatively positioning the divs, and not moving them to the correct spot.
Working JSFiddle:
http://jsfiddle.net/seanjohnson08/rVVuc/6/
.wrapper {
overflow: hidden;
height: 100%;
position: relative;
}
.div {
position: absolute;
height: 100%;
width: 100%;
top: 100%;
}
.current{
top: 0;
}
If you are looking for a way to limit the amount of scroll events fired, try throttling: http://benalman.com/projects/jquery-throttle-debounce-plugin/. My solution doesn't require this, because no matter how many times it is firing the scroll event, it only ever tells jquery to animate to top:0, there's no chance of it animating past that.
so I wanted an animated footer for my webpage using jquery. There's supposed to be a button which should trigger the animation. I found a nice example for all this, and everything is fine and dandy. Except that the button (including the footer) has this code that makes it stick to the bottom of your web browser, rather than to the bottom of the page. I do [i]not[/i] want it to, like, "scroll" along with the page, I realy want it to be underneath all my other divs. I tried putting it in the div container (which has all my other divs in it as well), but that doesn't seem to work.
Now, (after 2.5 hours of googling) I found out that it might/may/could have something to do with "absolute" positioning in the CSS, so I tried switching some things around such as giving the footer's container a relative position or giving it an "overflow: hidden;" along with the rest a left float but nothing seemed to solve my problem. (I could've done something wrong, not that great with CSS after all :-/)
I hope someone is able/willing to help.
P.S. Here's the example I used:
http://return-true.com/2010/04/jquery-pop-up-footer-version-2/
and here's the code:
Javascript:
jQuery(function($) {
var open = false;
$('#footerSlideButton').click(function () {
if(open === false) {
$('#footerSlideContent').animate({ height: '300px' });
$(this).css('backgroundPosition', 'bottom left');
open = true;
} else {
$('#footerSlideContent').animate({ height: '0px' });
$(this).css('backgroundPosition', 'top left');
open = false;
}
});
});
HTML:
<div id="footerPlacement">
<div id="footerSlideContainer">
<div id="footerSlideButton"></div>
<div id="footerSlideContent">
<div id="footerSlideText">
<h3>Hey! I'm a Sliding Footer</h3>
<p>What's a Sliding Footer? Well I'm a cool little element which can be hidden from view, and revealed when the user wants to see me.</p>
<p>What can you use me for? Well look at all this stuff:</p>
<ul>
<li>Sales information</li>
<li>Important updates</li>
<li>Unobtrusive about panel</li>
<li>Or just a good ol' footer</li>
</ul>
<p>There are obviously many other uses, but these are the few useful ones I can think of.</p>
</div>
</div>
</div>
</div>
CSS:
#footerPlacement {
margin-bottom: 0px;
width: 1000px;
margin-left: auto;
margin-right: auto;
}
#footerSlideContainer {
position: fixed;
margin-left: 0px;
bottom:0px;
width: 1000px;
}
#footerSlideButton {
background: url('../images/footer/footerbtn.png') top left no-repeat transparent;
position: absolute;
top: -55px;
right: 20px;
width:50px;
height:50px;
border: none;
cursor: pointer;
}
#footerSlideContent {
width: 100%;
height: 10px;
background: #251b15;
color: #CCCCCC;
font-size: 0.8em;
border: none;
font-family: DejaVuSansBook, Sans-Serif;
}
#footerSlideText {
padding: 15px 10px 25px 25px;
}
Thanks in advance!
if you change your #footerPlacement to include position:relative, you can change #footerSlideContainer to be position:absolute and then your footer will sit below any content above it.
However you will need to make the content have a min-height of around 350px for the footer to work properly and if your content isn't long enough, the footer won't be at the bottom of the browser.
I also added overflow:hidden to #footerSlideContent. I have made a fiddle to demonstrate:
http://jsfiddle.net/tc6b8/
I am trying to create a carousel, where clicking on any element will slide it leftwards, simultaneously sliding the right element into viewport. For that, I need to have the divs stacked side by side. I am trying it out as a float based layout (see Fiddle ).
Problem is that here clicking the red colored div slides it leftward alright, but not the green element leftwards. This is probably due to the fact that they are actually lying below another, as visible when the overflow: hidden is removed from #cont's style. How elese to stack them side by side so that sliding one leftward automatically slides the next one leftwards as well? (Creating the to-be-next element on the fly while clicking and animating it into viewport is a no-no, the element should be present in the DOM!)
I'd suggest you use a plugin, as there is more to this than you may realize. There are many plugins out there for this, here's a list to get you started: http://www.tripwiremagazine.com/2012/12/jquery-carousel.html
I modified your Javascript, HTML, and CSS to get you pointed in the right direction:
http://jsfiddle.net/nf5Dh/2/
You need a container contContent, positioned absolutely, and that container gets moved within the container div. You just float the elements in contContent to get them next to each other.
HTML:
<div id='cont'>
<div id="contContent">
<div id='i1'></div>
<div id='i2'></div>
<div id='i3'></div>
</div>
</div>
CSS:
#cont {
width: 50px;
padding-top: 10px;
background: blue;
height: 50px;
overflow: hidden;
position: relative;
}
#contContent {
height: 50px;
width: 150px;
position: absolute;
top: 0;
left: 0;
}
#contContent > div {
float: left;
display: inline-block;
height: 50px;
width: 50px;
}
#i1 { background: red; }
#i2 { background: green; }
#i3 { background: yellow; }
And the JS:
$("#contContent > div").click(function(){
$("#contContent").animate({left: "-=50px"},1000);
});
You'd probably be better off using an ul instead of all divs, this is at least more semantically correct, though not technically necessary.
<div id="carousel">
<ul id="carouselContent">
<li id="slide1"></li>
<li id="slide2"></li>
<li id="slide3"></li>
</ul>
</div>
This:
#cont {
white-space:nowrap;
overflow: hidden;
}
.pane { // or whatever the slide divs are called. get rid of the float.
float: none;
display: inline-block;
*zoom:1;
*display:inline;
}
You can use that carousel where you can generate javascript for the carousel http://caroufredsel.dev7studios.com/configuration-robot.php
I've used http://sorgalla.com/jcarousel/ for things like this in the past, that's based on postion: relative and left/right offsets. Probably easier than messing with floats.
You can try using a list item instead, and display them inline.