How to add loading DIV for angular js application? - javascript

I have simple application with angularjs and while data load in background it shows blank page, after angular js complete loading the template then I can view the data.
I want to add loading spinner while loading and once the loading complete then it should hide.
Almost 50-100 records, with images as well.
<ul id='example-messages' class='large-block-grid-1'>
<li ng-repeat='msg in messages'>
<!--<strong class='example-chat-username'>{{msg.startTime}}</strong>
{{msg.endTime}} -->
<h4><a ng-href="{{msg.offerUrl}}">{{msg.offerName}}</a></h4>
<div class="row">
<div class="medium-4 columns">
<a ng-href="{{msg.offerUrl}}"><img src="image.jpg" /></a>
</div>
<div class="medium-8 columns">
<h5><a ng-href="{{msg.offerUrl}}">{{msg.offerCondition}}</a></h5>
<h6>{{msg.offerDescription}}</h6>
<div class="row" style="padding-top:22px">
<div class="medium-5 columns">
<div class="alert-box success radius">{{msg.startTime}}</div>
</div>
<div class="medium-5 columns">
<div class="alert-box warning radius">{{msg.endTime}}</div>
</div>
</div>
</div>
</div>
</li>
</ul>

This is exactred from one of my live Angular projects:
HTML (index.html):
<div ng-controller="MainCtrl">
<div ng-cloak ng-show="loading" id="overlay">
<div class="loader"></div>
</div>
</div>
SCSS (basically just to keep the #overlay fixed on top of other layers, and have a nice animation applied to .loader):
#overlay {
background: rgba(0,0,0,.85);
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 9999;
}
$colors:
hsla(337, 84, 48, 0.75)
hsla(160, 50, 48, 0.75)
hsla(190, 61, 65, 0.75)
hsla( 41, 82, 52, 0.75);
$size: 2.5em;
$thickness: 0.5em;
// Calculated variables.
$lat: ($size - $thickness) / 2;
$offset: $lat - $thickness;
.loader {
position: relative;
width: $size;
height: $size;
transform: rotate(165deg);
&:before,
&:after {
content: '';
position: absolute;
top: 50%;
left: 50%;
display: block;
width: $thickness;
height: $thickness;
border-radius: $thickness / 2;
transform: translate(-50%, -50%);
}
&:before {
animation: before 2s infinite;
}
&:after {
animation: after 2s infinite;
}
}
Then of course, in the controllers, whenever you want to show or hide the loading indicator:
$scope.root.loading = true;
$scope.root.loading = false;

You can add a scope boolean variable with value set to false, and change the value to true in your http promise success.
JS code sample:
function myController($scope, YourDataServer) {
$scope.dataLoaded = false;
YourDataServer
.query()
.$promise
.then(
function(result) {
$scope.dataLoaded = true; // set the value to true
});
}
HTML would look like:
<div id="loadingBar" ng-show="!dataLoaded">Loading...</div>
<div id="dataWrapper" ng-show="dataLoaded">
<!-- data goes here -->
</div>

below are few links of loading indicator
angular-spinner or angular-sham-spinner
also read this BLOG which details on how the spinner works with angularjs
also if you want to implement it yourself, below code will get you started...
app.directive("spinner", function(){
return: {
restrict: 'E',
scope: {enable:"="},
template: <div class="spinner" ng-show="enable"><img src="content/spinner.gif"></div>
}
});
i havent tested the code but directive wont be more complex than this...

Related

CSS Effects, Hover over a div Container and all the other div Containers lower the opacity [duplicate]

This question already has an answer here:
Change opacity on all elements except hovered one
(1 answer)
Closed 2 years ago.
I am working on a Website where I created 5 different Blocks with a div container. Now I added a CSS effect which makes the div container pop up if you hover over it.
.site-block {
position: relative;
width: 18%;
height: 345px;
background-color: #23253b;
margin: 8px;
border-radius: 12px;
top: 0;
transition: 0.5s;
}
.site-block:hover {
transform: scale(1.06);
}
HTML for 1 Block
<div class="site-block">
<div class="site-logo">
<img src="img/sites/csgoempire-logo.png"/>
</div>
<div class="bonus">
<p>Get a free case!</p>
</div>
<br>
<div class="deposit-methods">
<img src="img/deposit-methods/btc-deposit.png" alt="G2A" />
<img src="img/deposit-methods/eth-deposit.png" alt="CSGO" />
</div>
<div class="code">
<a>Primatcodes</a>
<img src="img/copy.png" alt="CSGO" />
</div>
<div class="site-url">
<a href="https://daddyskins.com/promo-code/Primatcodes">Claim
</a>
</div>
</div>
Now I want to add another effect which should blur out all the other blocks. So bassicaly if I hover over a block I want that block to pop out and have a opacity of 1 and the other 4 should lower their opacity to 0.2. Is that possible with CSS or Javascript? and if yes HOW
Looking forward to your answers!
Not sure if there is a CSS way, but here is a javascript native way using mouseenter and mouseleave events:
.container {
display:flex;
}
.site-block {
position: relative;
width: 18%;
height: 200px;
background-color: #23253b;
margin: 8px;
border-radius: 12px;
top: 0;
transition: 0.5s;
color: #FFF;
}
.site-block:hover {
transform: scale(1.06);
}
<div class="container">
<div class="site-block">
<p>AAA</p>
</div>
<div class="site-block"><p>AAA</p></div>
<div class="site-block"><p>AAA</p></div>
<div class="site-block"><p>AAA</p></div>
</div>
<!-- first try it like this, then move it to file, just make sure your HTML above js tag ☝️and its before </body> -->
<script>
const siteBox = document.querySelectorAll('.site-block');
siteBox.forEach(function(element){
element.addEventListener('mouseenter', function(event) {
siteBox.forEach((box) => {
if(event.target !== box) {
//box.style.opacity = 0.2;
box.style.backgroundColor = 'rgba(35, 37, 59, 0.2)';
box.style.color = '#000';
}
});
event.target.opacity = 1;
});
element.addEventListener('mouseleave', function(event) {
siteBox.forEach((otherBox) => {
otherBox.style.backgroundColor = 'rgb(35, 37, 59)';
otherBox.style.color = '#FFF';
});
});
});
</script>

Animating Multiple Divs

The following code works, but I have a problem since I want to have multiple portfolio objects like this one. If I use the current code it would raise all of the hidden divs (.slide) with text instead of one at a time based on hover. I can't use "this" since that would just make the picture animate upward. I could give everything ids and write a lot of JavaScript code that is repetitive, but I am almost positive that isn't the best way to do things.
Basically, How would you target a div with a hover effect that causes another div to do something and still be able to reuse the code?
The HTML for this section:
<div class="col-md-6 high">
<img class="port" src="http://loremflickr.com/320/240" alt="test">
<div class="slide">
<h3>Test Portfolio</h3>
</div>
</div>
The CSS for this section:
.high {
height: 200px;
overflow: hidden;
}
.port {
width: 100%;
height: 200px;
}
.slide {
background-color: rgba(74, 170, 165, 0.7);
color: white;
position: relative;
top: -34px;
height: 200px;
width: 100%;
padding: 20px;
text-align: center;
}
The JavaScript for this section:
$(document).ready(function(){
var portfolio = {
// moves div with text over portfolio picture on hover
hoverPort: function() {
$(".port").hover(function() {
$(".slide").stop().animate({"top" : "-110px"});
}, function() {
$(".slide").stop().animate({"top" : "-34"});
});
}, // end of hoverPort function
} // end of portfolio object
portfolio.hoverPort();
}); // end of document.ready
Of course you can use this, not to animate the element itself but to refer another "closest" element based on that:
$(".port").hover(function() {
$(this).next('.slide').stop().animate({"top" : "-110px"});
}, function() {
$(this).next('.slide').stop().animate({"top" : "-34"});
});
Demo Snippet
$(".port").hover(function() {
$(this).next('.slide').stop().animate({
"top": "-110px"
});
}, function() {
$(this).next('.slide').stop().animate({
"top": "-34"
});
});
.col-md-6 {
float: left;
width: 50%;
padding:25px;
box-sizing:border-box;
}
.slide {
position: relative;
top: -60px;
color: white;
background: red;
font-size: 2em;
font-family: sans-serif;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-md-6 high">
<img class="port" src="http://loremflickr.com/320/240" alt="test">
<div class="slide">
<h3>Test Portfolio</h3>
</div>
</div>
<div class="col-md-6 high">
<img class="port" src="http://loremflickr.com/320/240" alt="test">
<div class="slide">
<h3>Test Portfolio</h3>
</div>
</div>
You can use jQuery "eq" selector.
$(".port").eq(0).hover(function() {
$(".slide").eq(0).stop().animate({"top" : "-110px"});
});
Hovering over the first "port" will animate the first "slide".

Panels like JSFiddle

I have this,
I want,
Fiddle
When Seconds tab goes up, I want to decrease height of First Section with min First 2 showing always, same with Second section.
$('#second').resizable({
handles: {
'n': '#ngrip',
},
resize: function () {
var b = $('#second').height();
var a = $('#first').css("height", b + "px");
console.log(a.height());
}
});
Edit
Must have -- I want it to work just like JSFiddle "HTML" and "JavaScript" panels, they both are resizable but also have min heights as you can see here
http://jsfiddle.net/
$('#second').resizable({
handles: {
'n': '#ngrip',
},
maxHeight: 300,
minHeight: 150,
resize: function (event, ui) {
var h = ui.size.height;
$('#first').height(400 -h);
}
});
#main {
width:100%;
height:400px;
overflow: hidden;
position: relative;
}
#first, #second {
height:200px;
width: 100%;
overflow-y: scroll;
}
#second {
z-index:999;
position: absolute;
}
#first-head, #second-head {
background-color:red;
}
#ngrip {
position: relative;
width: 10px;
height: 10px;
background-color: #ffffff;
border: 1px solid #000000;
bottom: -5px;
left: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="http://code.jquery.com/ui/1.8.18/jquery-ui.min.js"></script>
<div id="main">
<div id="first">
<div id="first-head">
<h3>First</h3>
</div>
<div id="first-body">
<p>First-1</p>
<p>First-2</p>
<p>First-3</p>
<p>First-4</p>
<p>First-5</p>
<p>First-6</p>
</div>
</div>
<div id='second'>
<div id="second-head">
<h3>Second</h3>
<div class="ui-resizable-handle ui-resizable-n" id="ngrip"></div>
</div>
<div id="second-body">
<p>Second-1</p>
<p>Second-2</p>
<p>Second-3</p>
<p>Second-4</p>
<p>Second-5</p>
<p>Second-6</p>
</div>
</div>
</div>
Use minHeight and minHeight option of JqueryUI combined with CSS display: absolute; for #second
First, change your resize direction in HTML (from ui-resizable-s to ui-resizable-n)
<div class="ui-resizable-handle ui-resizable-n" id="ngrip"></div>
Second, use JqueryUI options in Javascript:
$('#second').resizable({
handles: {
'n': '#ngrip',
},
maxHeight: 300, // Example max height of `#second` is 300px
minHeight: 100, // Example min height of `#second` is 100px
resize: function (event, ui) {
// Get height of `#second`
var h = ui.size.height;
// Set height of `#first`
$('#first').height(400 - h); //400 is height of container `#main`
}
});
Final, change some CSS
#main {
width:100%;
height:400px;
overflow: hidden;
position: relative;
}
#first, #second {
height:200px;
width: 100%;
overflow-y: scroll;
}
#second {
z-index:999;
position: absolute;
}
#first-head, #second-head {
background-color:red;
}
#ngrip {
position: relative;
width: 10px;
height: 10px;
background-color: #ffffff;
border: 1px solid #000000;
bottom: -5px;
left: 50%;
}
Hope it help you.
Please Check this demo JS Fiddle. It will useful for you.
HTML
<div id="main">
<div id="first">
<div id="first-head">
<h3>First</h3>
</div>
<div id="first-body">
<p>First-1</p>
<p>First-2</p>
<p>First-3</p>
<p>First-4</p>
<p>First-5</p>
<p>First-6</p>
</div>
</div>
<div id='second'>
<div id="second-head">
<h3>Second</h3>
<div class="ui-resizable-handle ui-resizable-s" id="ngrip"></div>
</div>
<div id="second-body">
<p>Second-1</p>
<p>Second-2</p>
<p>Second-3</p>
<p>Second-4</p>
<p>Second-5</p>
<p>Second-6</p>
<p>Second-7</p>
<p>Second-8</p>
<p>Second-9</p>
</div>
</div>
</div>
CSS
#main {
width:100%;
height:400px;
}
#first, #second {
min-height:100px;
height:170px;
max-height:400px;
}
#second-body{
z-index:9999;
}
#first-head, #second-head {
background-color:red;
}
#first-body, #second-body {
overflow-y:auto;
height:100%;
margin-bottom:10px;
}
#ngrip {
position: absolute;
width: 10px;
height: 10px;
background-color: #ffffff;
border: 1px solid #000000;
top:0px;
left: 50%;
}
jQuery
$('#second').resizable({
handles: {
'n': '#ngrip',
},
resize: function () {
var b = $('#second').height();
var height=$('#main').height();
var a = $('#first').css("height", b + "px");
var first=$('#first').height();
$('#second').css("height",height- first+ "px");
}
});
try this below line
<div id="first" style="min-height:35%;overflow:hidden">
instead of
<div id="first">
Live Examples
Minimal Example
Full Example
Explanation
Your second comment was close to all that's required.
The "key insight" is that, in order to constrain the minimum height of one element, it suffices to constrain the maximum height of the other. If the top element cannot be taller than 250, then the bottom element cannot be any smaller than 50 (to maintain a constant container height of 300).
Relevant JavaScript
// initialise dimensions
var containerHeight = $("#container").height();
var minHeight = containerHeight * 0.30; // min 30% height
var maxHeight = containerHeight - minHeight;
// call rebalance once on page load to make sure the panels start off right
rebalance()
$("#top").resizable({
handles: 's',
maxHeight: maxHeight,
minHeight: minHeight,
resize: rebalance // whenever we resize, rebalance the panels
});
function rebalance() {
var currentTopHeight = $("#top").height();
$("#bottom").height(containerHeight - currentTopHeight);
}
I've also taken the liberty of cleaning up your code a little. I think you were having CSS problems related to filling the space after the header, and once that was fixed the resizing is fairly straightforward. I've annotated the CSS with comments to explain what's going on. You might also be interested in the discussion here: Make a div fill the height of the remaining screen space
Relevant CSS
/* both containers are full-width, and absolutely positioned in their parent */
#first, #second {
position:absolute;
width:100%;
}
/* pin the first to the top, and the second to the bottom */
#first {
top:0;
}
#second {
top:50%;
bottom:0;
}
/* The body needs to leave space at the top for the header (25px) but none at the bottom */
#first-body, #second-body {
overflow-y:auto;
width:100%;
position:absolute;
top:25px;
bottom:0;
}
I came across a plugin that looks very promising:
http://nathancahill.github.io/Split.js/
Split.js is a lightweight, unopinionated utility for creating adjustable split views or panes.
No dependencies or markup required, just two or more elements with a common parent.
Views can be split horizontally or vertically, with draggable gutters inserted between every two elements.
There is even a JS Fiddle-style Demo.
Sample JS (from demo):
Split(['#a', '#b'], {
gutterSize: 8,
cursor: 'col-resize'
})
Split(['#c', '#d'], {
direction: 'vertical',
sizes: [25, 75],
gutterSize: 8,
cursor: 'row-resize'
})
Split(['#e', '#f'], {
direction: 'vertical',
sizes: [25, 75],
gutterSize: 8,
cursor: 'row-resize'
})
Sample html usage (from demo):
<div id="a" class="split split-horizontal">
<div id="c" class="split content"></div>
<div id="d" class="split content"></div>
</div>
<div id="b" class="split split-horizontal">
<div id="e" class="split content"></div>
<div id="f" class="split content"></div>
</div>

Absolute CSS positioning with a top margin

I have a sidebar with some text and a footer inside it (which sticks to the bottom of the sidebar). When I resize (reduce) the window's height to e.g. half, the footer goes on top of the other texts in the sidebar. Is there a way to have a margin-top for example, so that when the window get resized, the footer keeps its position at the bottom until it is about to go on top of other elements (before it)?
.sidebar {
position: fixed;
width: 260px;
overflow-y: auto;
border-right: 1px solid #dadada;
display: inline-block;
background-color: #BDE6CA;
float: left;
z-index: 3;
}
.sidebar-content {
position: relative;
height: 100%;
width: 100%;
}
.sidebar-option {
color: #00aa4f;
font-size: 20px;
cursor: pointer;
padding: 20px 0px 20px 20px;
}
.sidebar-bottom {
bottom: 0px;
position: absolute;
width: 100%;
padding: 0px 40px 20px 0px;
text-align: right;
}
<div class="sidebar max-height">
<div class="sidebar-content">
<div class="sidebar-top">
<img class="sidebar-logo" src="http://lorempixel.com/50/50">
<div class="sidebar-option">
<img src="http://lorempixel.com/50/50">
<span>Section 1</span>
</div>
<div class="sidebar-option">
<img src="http://lorempixel.com/50/50">
<span>Section 2</span>
</div>
</div>
<div class="sidebar-bottom">
<div class="sidebar-text"><span>Sidebar footer</span>
</div>
</div>
</div>
</div>
You may add padding-bottom:40px; (example) to .sidebar-top or .sidebar-content, so there will be enough space for .sidebar-bottom
I realized this functionality cannot be done only in CSS, we need Javascript for detecting window resize and then applying CSS attributes conditionally. Since I am already using Angular.js, I prefer an Angular.js way, but the same can be done in pure Javascript or jQuery.
Using scope.$watch in a custom directive, I can detect window resize, conditionally apply CSS to the footer element (using the ng-style directive on the footer) and finally calling scope.$apply() (in my directive) to force a digest.
The "demo 3" fiddle in the first answer to this question helped a lot. Here is my fiddle. The most relevant part is applying the custom directive ("resize") and ng-style to the footer element:
<div class="sidebar-bottom" ng-style="changePosition()" resize>
<div class="sidebar-text"><span>Footer Text 1</span></div>
<div class="sidebar-text"><span>Footer Text 2</span></div>
</div>
and the directive itself and the function scope.changePosition():
app.directive('resize', function ($window) {
return function (scope, element, attr) {
var w = angular.element($window);
scope.$watch(function () {
return {
'h': window.innerHeight,
'w': window.innerWidth
};
}, function (newValue, oldValue) {
scope.changePosition = function () {
var pos ="";
if (newValue.h < 440) {
pos = "relative"
} else {
pos = "absolute"
}
return {
'position': pos
};
};
}, true);
w.bind('resize', function () {
scope.$apply();
});
}
});
And the default/initial style for the footer div:
.sidebar-bottom {
bottom: 0px;
position: absolute;
}

Display inline DIV

I just created a star rating system that change image on mouse over., but i cant seem to display the stars inline.
they get under each other.
It dosent work with style sheet so I suppose it should be re written in the javascript. !?
This is my JavaScript function.
html code :
<div id="star">
<div id="star_1" onclick="SendRating(1);" onmouseover="rateStar(1)" >
<img src="star2.png" id="rating_1" onclick="SendRating(this.getAttribute('score'));" alt="star_1" /></div>
<div id="star_2" onclick="SendRating(2);" onmouseover="rateStar(2)" >
<img src="star2.png" id="rating_2" onclick="SendRating(this.getAttribute('score'));" alt="star_2" /></div>
<div id="star_3" onclick="SendRating(3);" onmouseover="rateStar(3)" >
<img src="star2.png" id="rating_3" onclick="SendRating(this.getAttribute('score'));" alt="star_3" /></div>
<div id="star_4" onclick="SendRating(4);" onmouseover="rateStar(4)" >
<img src="star2.png" id="rating_4" onclick="SendRating(this.getAttribute('score'));" alt="star_4" /></div>
<div id="star_5" onclick="SendRating(5);" onmouseover="rateStar(5)" >
<img src="star2.png" id="rating_5" onclick="SendRating(this.getAttribute('score'));" alt="star_5" /></div>
<p id="ContentHolder">
</p>
</div>
JavaScript :
function rateStar(rating){
var i = 1;
var ratings = '';
for (i==1; i<=5; i++){
if (i<=rating){
document.getElementById('rating_'+i).src= 'star1.png';
}
else{
document.getElementById('rating_'+i).src= 'star.jpg';
}
}
}
and one of my divs
<div id="star_1" onclick="SendRating(1);" onmouseover="rateStar(1)" >
<img src="star.jpg" id="rating_1" onclick="SendRating(this.getAttribute('score'));" alt="star_1" /></div>
CSS
#star{
position:absolute;
color:#fff;
margin-top:100px;
margin-left:1000px;
display:inline block;
}
the mouse over function is working great except that it wont display inline =/
Thanks
Using display: inline-block; on your stars will fix the problem. You can do the whole hover effect using CSS without any Javascript.
Demo: http://jsfiddle.net/ThinkingStiff/5JPDX/
HTML:
<div id="stars">
<div id="star-1" class="star"></div>
<div id="star-2" class="star"></div>
<div id="star-3" class="star"></div>
<div id="star-4" class="star"></div>
<div id="star-5" class="star"></div>
</div>
CSS:
#stars {
background-image: url( http://thinkingstiff.com/images/star-empty.gif );
background-size: 20px 20px;
cursor: pointer;
height: 20px;
overflow: hidden;
position: relative;
width: 100px;
}
.star {
height: 20px;
position: absolute;
width: 100px;
}
.star:hover {
background-image: url( http://thinkingstiff.com/images/star-highlight.png );
background-size: 20px 20px;
}
#star-1 {
right: 80px;
z-index: 5;
}
#star-2 {
right: 60px;
z-index: 4;
}
#star-3 {
right: 40px;
z-index: 3;
}
#star-4 {
right: 20px;
z-index: 2;
}
#star-5 {
right: 0;
z-index: 1;
}
Script:
document.getElementById( 'stars' ).addEventListener( 'click', function ( event ) {
//SendRating( event.target.id.substr( -1 ) );
alert( event.target.id.substr( -1 ) );
}, false );
Output:
float:left; display:inline; or display:inline block; are all your friends when trying to display in a straight horizontal line. I won't suggest using a <TABLE> for this but it can be done that way.
Maybe you should post some more of your code or create a JSFiddle of your HTML/CSS/Javascript
Update:
Created this: http://jsfiddle.net/Uyr4P/
It's just a copy/paste of your HTML with a display:inline-block style added for DIVs to illustrate how it is all in one line.
You will instead probably want to place a rule on your outermost DIVs and control the display that way - alternatively, use SPANs instead of DIVs
DIV solution. Just use this with your current HTML:
DIV#star DIV
{
display:inline-block;
}
You should use CSS property "display" not on parent DIV, but on child ones, because it cannot be inherited. So, do something like this in CSS:
#star_1{display:inline block;}
#star_2{display:inline block;}
#star_3{display:inline block;}
#star_4{display:inline block;}
#star_5{display:inline block;}
or (better) declare CSS class for it

Categories

Resources