How to show some HTML until screen is loaded in Angular / Ionic? - angularjs

I am using Ionic and I can't find the solution for my problem. What I want to do, is to show some HTML before the screen is loaded. You can use the default $ionicLoading, but that just gives me an overlay, while I don't want that. I am a newbie to Angular and Ionic, so it might be a very simple question, but I just can't solve it.
To do so, I have added HTML to the screen I wanted it to be added. I made it like this:
<div class="preload-wrapper" ng-show="removeAfterLoad">
<p>Please wait, the page is being loaded </p>
</div>
And I know I need to use this, but I don't know how to bind it to the HTML I am using.
$ionicPlatform.ready(function removeAfterLoad () {
// I need to make sure that the HTML is only shown while the screen is being loaded.
// After it is loaded, I want to remove the HTML.
});
Is it something like $scope.hide I need to use. If so, how do I bind that to my HTML snippet?

I would recommend using ng-cloak
adding ng-cloak to a tag will hide it until the page is fulling loaded, and can be used in the inverse manner.
Step 1
Add this style between your <head> tag.
[ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
display: none !important;
}
[ng-cloak].loading {
margin-top: 150px;
text-align: center;
display: block !important;
}
.loading {
display: none;
}
Step 2:
Add this to your index.html
<div class="loading" ng-cloak>
<i class="fa fa-spinner fa-pulse fa-3x fa-fw"></i>
<span class="sr-only">Loading...</span>
</div>
<div class="container" ng-cloak>
.....content goes here
</div>
After the page has fully loaded, ng-cloak will add "hidden" to the loading div and display the container div.

It's Actually Quiet Simple:
Inside Your Controller, you need to add $ionicLoading as below -
$ionicLoading.show({
template: '<ion-spinner></ion-spinner> <br/> Please wait, the page is being loaded'
});
And Hide after the function is successfully Callback:
$ionicLoading.hide();

You can actually override $ionicLoading template/overlay with your own html code. Here are the docs: http://ionicframework.com/docs/api/service/$ionicLoading/
You can even override the default template for any view.
In your example you could do:
angular.module('LoadingApp', ['ionic'])
.controller('LoadingCtrl', function($scope, $ionicLoading) {
$scope.show = function() {
$ionicLoading.show({
template: '<div class="preload-wrapper" ng-show="removeAfterLoad"> '+
'<p>Please wait, the page is being loaded </p> '+
'</div>',
duration: 3000,
//if you want to hide the background overlay
noBackdrop: true
}).then(function(){
console.log("The loading indicator is now displaying your html");
});
};
$scope.hide = function(){
$ionicLoading.hide().then(function(){
console.log("The loading indicator is now hidden");
});
};
});
An nice way to show and hide loading is using ionic view events: http://ionicframework.com/docs/api/directive/ionView/
$scope.$on("$ionicView.beforeLeave", function(event, data){
// show loading
});
$scope.$on("$ionicView.beforeEnter", function(event, data){
// hide loading
});

Related

How to show a progress bar in AngularJS

i'm kind of new using AngularJs framework and i am not that good in English. so i hope somebody can help me solve my problem and never mind my grammar hehe. i know mostly of progress bar in angularjs triggered by ng-show, but what if i want to put a progress bar before an object tag loads. for example
<div class="progress">
<div class="progress-bar" role="progressbar" aria-valuenow="70"
aria-valuemin="0" aria-valuemax="100" style="width:70%">
<object width="400" height="400" data="file.pdf"></object>
</div>
</div>
let assume that that "file.pdf" is being fetch from the server. that being said it needs time to load, so i want to put a progress bar on that time while the data if being fetch from the server and hide it when the object is fully loaded thank you guys.
data flow example :
(file.pdf) ----Fetching---- [controller]----Progress bar--View(html)
Hope this will help you out. This is a basic example for showing and hiding a spinner bar on button click.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Welcome to LearnKode - A code learning platform</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.2/angular.min.js"></script>
<style>
.loader {
border: 16px solid #f3f3f3; /* Light grey */
border-top: 16px solid #3498db; /* Blue */
border-radius: 50%;
width: 120px;
height: 120px;
animation: spin 2s linear infinite;
margin: 0 auto;
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
html, body, container {
height: 100%;
width: 100%;
margin: 0;
}
</style>
</head>
<body ng-app="changeExample">
<div class="container" ng-controller="ExampleController">
<button class="btn" ng-click="ShowSpinner()">Show Spinner</button>
<button class="btn" ng-click="HideSpinner()">Hide Spinner</button>
<div ng-if="ShowSpinnerStatus" class="loader"></div>
</div>
<script>
var app = angular.module("changeExample", []);
app.controller('ExampleController', ['$scope', function ($scope) {
$scope.ShowSpinnerStatus = true;
$scope.ShowSpinner = function(){
$scope.ShowSpinnerStatus = true;
};
$scope.HideSpinner = function(){
$scope.ShowSpinnerStatus = false;
};
}]);
</script>
</body>
</html>
You can show and hide the spinner on a service call like this.
$scope.ShowSpinner();
LoginService.authenticateUser(userName, password).then(
function(response){
$scope.HideSpinner();
if( response.isSuccess ){
// Login Success
}
else{
//Login Fail
}
},
function(error){
//Network related error
$scope.HideSpinner();
}
);
Your English is really good and you need not worry about it at all. Coming back to your question, you are on the right path. You would need to use ng-show or ng-hide, whatever you choose. Let's say you choose ng-show In your controller, you would declare a variable,
$scope.isProgessBarVisible = true;
and then, within the controller itself, upon return from http call from the server, you would set it to false.
$http.get('someUrl')
.then(function successCallback(response) {
//load you pdf file content
$scope.isProgessBarVisible = false;
}
And in the HTML
<div class="progress">
<div class="progress-bar" role="progressbar" ng-show="isProgessBarVisible" aria-valuenow="70"
aria-valuemin="0" aria-valuemax="100" style="width:70%">
<object width="400" height="400" data="file.pdf"></object>
</div>
With this in place, the progress bar will show up until the file is fetched from server and displayed.
I think the problem is not just about showing/hiding the progress bar, perhaps it is about how to hide the progress bar when the <object>'s content finish loading.
Initially, I tried to use ng-load on the <object> but somehow it didn't work. So I tried to use onload which does work. But since the onLoad() handler function is outside angular environment, I had to get back the angular scope to be able to set the variable $scope.showProgress that will hide the progress bar.
See the plunkr yourself, and let me know if that is what you are looking for.
Plunkr https://plnkr.co/edit/wxgetLZdST0WcPEHyraZ
Note: I don't know whether it is possible to get the progress status number (% loaded), but at least we can show "Loading..." or a spinner icon while the <object> is loading.
http://chieffancypants.github.io/angular-loading-bar/
angular.module('app', ['angular-loading-bar']);
angular-loading-bar is a good option for $http calls

AngularJS directive data binding inside a popover

Hi I'm creating an Angular bootstrap popover, and the popover contains a directive. The user story is that when the user clicks on a row inside an ui-grid table, the popover will show. But it seems that in HTML code the data is not actually passed into the directive. Related code is here:
search.tpl.html:
<div class="gridStyle" ui-grid="vm.selectedTypes" ui-grid-resize-columns ui-grid-selection style="margin-top: 0px; z-index: 4; position: relative">
</div>
<script type="text/ng-templae" id="popover.html">
<div style="z-index:10; position: relative">
<type-view type="vm.type" domain="vm.domain" pos="{top: 0, left: 0}">
</type-view>
</div>
</script>
search.js:
//In configure
controllerAs: "vm",
...
//In controller
var vm=this;
vm.type=[...];
vm.domain=[...]; //both var get values inside
Now the popover is shown, and the directive is inside, but the values (vm.type and vm.domain) are not injected into the directive; I checked the console, and in the directive 'pos' is injected, so I suppose maybe it's because the scope is different inside a popover and directly using vm.sth will not work. How can I resolve this? Thanks!

angular js ngdialog scrollbar

I am using ng-dialog to display the popup. The problem i am facing with ng-dialog is there is no vertical scroll bar on the dialog box when the message is huge but scroll bar appearing for the entire html page.
Is there a way i can bring the scroll bar on the ng-dialog box.
I am using the ngdialog.js from https://github.com/likeastore/ngDialog
I googled my best but not getting any idea about how to bring the scrollbar. Please i am just bigger in the css.
below is the code which i am using to bring the popup.
ngDialog.open({ template: 'resources/views/popup.html', className: 'ngdialog-theme-default' , scope: $scope });
any suggestion much appreciated.
You should set overflow-y: scroll; on your content element within your dialog template.
HTML:
<div class="modal-content">
<ul class="list-group">
<li class="list-group-item" ng-repeat="item in items">{{::item.name}}</li>
</ul>
LESS:
.modal-content {
.choose-modal-content {
height: 100%;
width: 100%;
ul {
&.list-group {
overflow-y: scroll;
}
}
}
}
This way the ul will be scrollable when the content overflows.

How to make simple animation using ngAnimate

I am not able to understand how the ngAnimate works exactly. here is my doubt.
1) ngAnimate - only works on directives?
2) how to make ng-animate work without the directive
3) Any of above way, how to add call back after animation complete?
Because i see all the animation examples only with directives.
I have a small demo here, any one help me to animation both without directive and with directive approach to simply adding a class name as `fade'?
my CODE:
<div class="container" ng-app="myApp">
<div class="content" ng-controller="count">
<h1 ng-click="animate()">Click ME</h1>
<h2>Let me Fade</h2>
</div>
</div>
<div class="container" ng-app="myApp">
<div class="content" ng-controller="count">
<h1 ng-click="animate()">Click ME</h1>
<h2>Let me Fade</h2>
</div>
</div>
Demo to update
I am not able to understand how the ngAnimate works exactly. here is
my doubt.
ngAnimate is a module that provides support for animations in angular apps. There are two ways to make use of animations when ngAnimate is used: by using CSS and JavaScript. For CSS based animations, angularjs adds a class ng-enter/ng-leave whenever an element is shown/removed from 'view'. You simply need to play with these classes to make the animation work!
Prerequisite:
You would need to add the library for angular-animate
<script src="ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular-animate.js">
</script>
and include ngAnimate as the dependency in your myApp module.
var myApp = angular.module('myApp', ['ngAnimate']);
1) ngAnimate - only works on directives?
Yes. You cannot use ngAnimate without directive.
According to documentation, following directives are "animation aware":
ngRepeat, ngView, ngInclude, ngSwitch, ngIf, ngClass,
ngShow, ngHide, ngModel, ngMessages and ngMessage
2) how to make ng-animate work without the directive
You cannot!. Remember, even ng-click is a directive
3) Any of above way, how to add call back after animation complete?
Yes, You can add a callback after the animation is complete using the $animate service(which would usually be done in a custom directive) and use $animate.leave(element, [options]);
Have a look at this example for triggering events after the animation ends.
Finally, here is the updated demo you mentioned in question.
You may toggle a flag to true/false with each click on <h1> and make content inside <h2> hide/show based on flag.
<div class="container" ng-app="myApp">
<div class="content" ng-controller="count">
<h1 ng-click="animate()">Click ME</h1>
<h2 ng-if="flag" class="fade">Let me Fade</h2>
</div>
</div>
Also, you'd need to handle fade-effect with css
.fade.ng-enter {
transition:0.5s linear all;
opacity:0;
}
.fade.ng-enter.ng-enter-active {
opacity:1;
}
.fade.ng-leave {
transition:0.5s linear all;
opacity:1;
}
.fade.ng-leave.ng-leave-active {
opacity:0;
}
Hope it helps!
<div class="container" ng-app="myApp">
<div class="content" ng-controller="count">
<h1 ng-click="animate()">Click ME</h1>
<h2 ng-if="clicked" class="animate-if">Let me Fade</h2>
</div>
I added a variable named clicked which is set to true or false to animate the Let me Fade Text
var myApp = angular.module('myApp', []);
myApp.controller('count', function($scope) {
$scope.clicked=false;
$scope.animate = function () {
$scope.clicked=!$scope.clicked;
}
});
In this JS file upon clicking the click me button the variable clicked is set to true or false .
**
h2.fade {
opacity : 0;
transition: opacity 1s ease-in-out;
}
.animate-enter, .animate-leave {
transition: 500ms ease-in all;
position: relative;
display: block;
}
.animate-enter.animate-enter-active, .animate-leave {
left: 0;
}
.animate-leave.animate-leave-active, .animate-enter {
left: 500px;
}
**
Here in the css file i added css for the class animate which acts upon clicked variable if the variable is true it goes for animate-enter-active
otherwise it goes for leave-active

Animation on ngShow skips first time

I am trying to animate a twitter bootstrap panel body opening/closing that is shown with ng-show in angular (version 1.3.2), by using a simple jQuery slideUp/slideDown.
(I tried at first with css transitions, but couldn't do it because of unknown body height, and max-height animation was giving me problems on closing, so I decided to go with JS)
I've succeeded in making the animation, but it does not work the first time
the animation is toggled.
So the first body showing is not animated, then the hiding is animated, and after that everything is fine (both show and hide animate).
Javascript part:
app.animation('.animate-panel-body-slide', function(){
return {
addClass : function(element, className, done) {
$(element).slideUp(400, done);
return function(isCancelled) {
if(isCancelled) {
$(element).stop();
}
}
},
removeClass : function(element, className, done) {
$(element).slideDown(400, done);
return function(isCancelled) {
if(isCancelled) {
$(element).stop();
}
}
}
}
});
HTML part:
<div class="panel panel-default">
<div class="panel-heading">
HEADING
</div>
<div class="panel-body animate-panel-body-slide" ng-show="isPanelOpen">
SOME HTML IN BODY...
</div>
</div>
Am I missing something?
When removeClass is executed it's because ng-hide (which sets display: none) was removed from the element.
The first time this happens the element will have display: block which means the element will appear immediately and the slideDown animation will not be apparent.
When the panel is closed the slideUp animation will add style="display: none;" to the element, which means the next time it's opened it will work as expected.
If you add it manually like this:
<div class="panel-body animate-panel-body-slide" ng-show="isPanelOpen" style="display: none">
It will work as long as the panel always begins as closed.
If you want it to work for both cases you can add this:
removeClass: function(element, className, done) {
element.css('display', 'none');
element.slideDown(400, done);
...

Resources