Twitter Bootstrap's buttons have a nice Loading...
state available.
The thing is that it just shows a message like Loading...
passed through the data-loading-text
attribute like this:
<button type="button" class="btn btn-primary start" id="btnStartUploads"
data-loading-text="@Localization.Uploading">
<i class="icon-upload icon-large"></i>
<span>@Localization.StartUpload</span>
</button>
Looking at Font Awesome, you see that there's now an animated spinner icon.
I tried to integrate that spinner icon when firing an Upload
operation like this:
$("#btnStartUploads").button('loading');
$("#btnStartUploads i").removeAttr('class');
$("#btnStartUploads i").addClass('icon-spinner icon-spin icon-large');
but this had no effect at all, that is, I just see the Uploading...
text on the button.
Is it possible to add an icon when the button is in the Loading state? Looks like somehow Bootstrap just removes the icon <i class="icon-upload icon-large"></i>
inside the button while in the Loading state.
Here's a simple demo that shows the behavior I describe above. As you see when it enters the Loading state the icon just disappears. It reappears right after the time interval.
Simple solution for Bootstrap 3 using CSS3 animations.
Put the following in your CSS:
.glyphicon.spinning {
animation: spin 1s infinite linear;
-webkit-animation: spin2 1s infinite linear;
}
@keyframes spin {
from { transform: scale(1) rotate(0deg); }
to { transform: scale(1) rotate(360deg); }
}
@-webkit-keyframes spin2 {
from { -webkit-transform: rotate(0deg); }
to { -webkit-transform: rotate(360deg); }
}
Then just add the spinning
class to a glyphicon
while loading to get your spinning icon:
<button class="btn btn-lg btn-warning">
<span class="glyphicon glyphicon-refresh spinning"></span> Loading...
</button>
Based on http://www.bootply.com/128062#
Note: IE9 and below do not support CSS3 animations.
If you look at the bootstrap-button.js source, you'll see that the bootstrap plugin replaces the buttons inner html with whatever is in data-loading-text when calling $(myElem).button('loading')
.
For your case, I think you should just be able to do this:
<button type="button"
class="btn btn-primary start"
id="btnStartUploads"
data-loading-text="<i class='icon-spinner icon-spin icon-large'></i> @Localization.Uploading">
<i class="icon-upload icon-large"></i>
<span>@Localization.StartUpload</span>
</button>
HTML
with text in a tag property. :-)
data-loading-text
is deprecated since v3.3.5 and will be removed in v4.
There's now a full-fledged plugin for that:
http://msurguy.github.io/ladda-bootstrap/
To make the solution by @flion look really great, you could adjust the center point for that icon so it doesn't wobble up and down. This looks right for me at a small font size:
.glyphicon-refresh.spinning {
transform-origin: 48% 50%;
}
.glyphicon-refresh.spinning { transform-origin: 50% 58%; }
worked for me
{ transform-origin: 50% 49%; }
solve in my case where I'm using cog
instead.
A lazy way to do this is with the UTF-8 entity code for a half circle \25E0
(aka ◠
), which looks like ◠ and then keyframe animate it. It's a simple as:
.busy { animation: spin 1s infinite linear; display:inline-block; font-weight: bold; font-family: sans-serif; font-size: 35px; font-style:normal; color:#555; } .busy::before { content:"\25E0"; } @keyframes spin { 0% {transform: rotate(0deg);} 100% {transform: rotate(359deg);} }
Here's my solution for Bootstrap 4:
<button id="search" class="btn btn-primary"
data-loading-text="<i class='fa fa-spinner fa-spin fa-fw' aria-hidden='true'></i>Searching">
Search
</button>
var setLoading = function () {
var search = $('#search');
if (!search.data('normal-text')) {
search.data('normal-text', search.html());
}
search.html(search.data('loading-text'));
};
var clearLoading = function () {
var search = $('#search');
search.html(search.data('normal-text'));
};
setInterval(() => {
setLoading();
setTimeout(() => {
clearLoading();
}, 1000);
}, 2000);
Check it out on JSFiddle
These are mine, based on pure SVG and CSS animations. Don't pay attention to JS code in the snippet bellow, it's just for demoing purposes. Feel free to make your custom ones basing on mine, it's super easy.
var svg = d3.select("svg"), columnsCount = 3; ['basic', 'basic2', 'basic3', 'basic4', 'loading', 'loading2', 'spin', 'chrome', 'chrome2', 'flower', 'flower2', 'backstreet_boys'].forEach(function(animation, i){ var x = (i%columnsCount+1) * 200-100, y = 20 + (Math.floor(i/columnsCount) * 200); svg.append("text") .attr('text-anchor', 'middle') .attr("x", x) .attr("y", y) .text((i+1)+". "+animation); svg.append("circle") .attr("class", animation) .attr("cx", x) .attr("cy", y+40) .attr("r", 16) }); circle { fill: none; stroke: #bbb; stroke-width: 4 } .basic { animation: basic 0.5s linear infinite; stroke-dasharray: 20 80; } @keyframes basic { 0% {stroke-dashoffset: 100;} 100% {stroke-dashoffset: 0;} } .basic2 { animation: basic2 0.5s linear infinite; stroke-dasharray: 80 20; } @keyframes basic2 { 0% {stroke-dashoffset: 100;} 100% {stroke-dashoffset: 0;} } .basic3 { animation: basic3 0.5s linear infinite; stroke-dasharray: 20 30; } @keyframes basic3 { 0% {stroke-dashoffset: 100;} 100% {stroke-dashoffset: 0;} } .basic4 { animation: basic4 0.5s linear infinite; stroke-dasharray: 10 23.3; } @keyframes basic4 { 0% {stroke-dashoffset: 100;} 100% {stroke-dashoffset: 0;} } .loading { animation: loading 1s linear infinite; stroke-dashoffset: 25; } @keyframes loading { 0% {stroke-dashoffset: 0; stroke-dasharray: 50 0; } 50% {stroke-dashoffset: -100; stroke-dasharray: 0 50;} 100% { stroke-dashoffset: -200;stroke-dasharray: 50 0;} } .loading2 { animation: loading2 1s linear infinite; } @keyframes loading2 { 0% {stroke-dasharray: 5 28.3; stroke-dashoffset: 75;} 50% {stroke-dasharray: 45 5; stroke-dashoffset: -50;} 100% {stroke-dasharray: 5 28.3; stroke-dashoffset: -125; } } .spin { animation: spin 1s linear infinite; stroke-dashoffset: 25; } @keyframes spin { 0% {stroke-dashoffset: 0; stroke-dasharray: 33.3 0; } 50% {stroke-dashoffset: -100; stroke-dasharray: 0 33.3;} 100% { stroke-dashoffset: -200;stroke-dasharray: 33.3 0;} } .chrome { animation: chrome 2s linear infinite; } @keyframes chrome { 0% {stroke-dasharray: 0 100; stroke-dashoffset: 25;} 25% {stroke-dasharray: 75 25; stroke-dashoffset: 0;} 50% {stroke-dasharray: 0 100; stroke-dashoffset: -125;} 75% {stroke-dasharray: 75 25; stroke-dashoffset: -150;} 100% {stroke-dasharray: 0 100; stroke-dashoffset: -275;} } .chrome2 { animation: chrome2 1s linear infinite; } @keyframes chrome2 { 0% {stroke-dasharray: 0 100; stroke-dashoffset: 25;} 25% {stroke-dasharray: 50 50; stroke-dashoffset: 0;} 50% {stroke-dasharray: 0 100; stroke-dashoffset: -50;} 75% {stroke-dasharray: 50 50; stroke-dashoffset: -125;} 100% {stroke-dasharray: 0 100; stroke-dashoffset: -175;} } .flower { animation: flower 1s linear infinite; } @keyframes flower { 0% {stroke-dasharray: 0 20; stroke-dashoffset: 25;} 50% {stroke-dasharray: 20 0; stroke-dashoffset: -50;} 100% {stroke-dasharray: 0 20; stroke-dashoffset: -125;} } .flower2 { animation: flower2 1s linear infinite; } @keyframes flower2 { 0% {stroke-dasharray: 5 20; stroke-dashoffset: 25;} 50% {stroke-dasharray: 20 5; stroke-dashoffset: -50;} 100% {stroke-dasharray: 5 20; stroke-dashoffset: -125;} } .backstreet_boys { animation: backstreet_boys 3s linear infinite; } @keyframes backstreet_boys { 0% {stroke-dasharray: 5 28.3; stroke-dashoffset: -225;} 15% {stroke-dasharray: 5 28.3; stroke-dashoffset: -300;} 30% {stroke-dasharray: 5 20; stroke-dashoffset: -300;} 45% {stroke-dasharray: 5 20; stroke-dashoffset: -375;} 60% {stroke-dasharray: 5 15; stroke-dashoffset: -375;} 75% {stroke-dasharray: 5 15; stroke-dashoffset: -450;} 90% {stroke-dasharray: 5 15; stroke-dashoffset: -525;} 100% {stroke-dasharray: 5 28.3; stroke-dashoffset: -925;} }
Also available on CodePen: https://codepen.io/anon/pen/PeRazr
Here is a full-fledged css solution inspired by Bulma. Just add
.button {
display: inline-flex;
align-items: center;
justify-content: center;
position: relative;
min-width: 200px;
max-width: 100%;
min-height: 40px;
text-align: center;
cursor: pointer;
}
@-webkit-keyframes spinAround {
from {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
@keyframes spinAround {
from {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
.button.is-loading {
text-indent: -9999px;
box-shadow: none;
font-size: 1rem;
height: 2.25em;
line-height: 1.5;
vertical-align: top;
padding-bottom: calc(0.375em - 1px);
padding-left: 0.75em;
padding-right: 0.75em;
padding-top: calc(0.375em - 1px);
white-space: nowrap;
}
.button.is-loading::after {
-webkit-animation: spinAround 500ms infinite linear;
animation: spinAround 500ms infinite linear;
border: 2px solid #dbdbdb;
border-radius: 290486px;
border-right-color: transparent;
border-top-color: transparent;
content: "";
display: block;
height: 1em;
position: relative;
width: 1em;
}
The only thing I found that worked was a post here: https://stackoverflow.com/a/44548729/9488229
I improved it, and now it provides all these features:
Disable the button after click
Show an animated loading icon using native bootstrap
Re-enable the button after the page is done loading
Text goes back to original when page loading is done
Javascript:
$(document).ready(function () {
$('.btn').on('click', function() {
var e=this;
setTimeout(function() {
e.innerHTML='<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Searching...';
e.disabled=true;
},0);
return true;
});
});
You can use the Bootstrap spinner. Use "position: absolute" to make both buttons over each other. With the JavaScript code you can remove the front button and the back button will be displayed.
button { position: absolute; top: 50px; left: 150px; width: 150px; font-size: 120%; padding: 5px; background: #B52519; color: #EAEAEA; border: none; margin: 120px; border-radius: 5px; display: flex; align-content: center; justify-content: center; transition: all 0.5s; height: 40px } #orderButton:hover { color: #c8c8c8; }
Success story sharing
animation
and not-animation
?animation
instead of-animation
. With that change fine in FF and IE for me. The firefox animation doesnt look very smooth though.