How to add animation to angularjs uib-alert directive - angularjs

I want to add fade-in animation for new alerts pushed into array and fade-out for dismissed alerts.
Alerts are dismissed automatically after 5 seconds.
I've already included angular-animate ui-bootstrap and ui-bootstrap-tpls libraries.
How can i get these animations working?
See Demo: http://plnkr.co/edit/ecbCA7h2zVA4XnvUHfFX?p=preview
HTML
<html ng-app="myApp">
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script>
<script src="https://code.angularjs.org/1.5.0/angular-animate.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.1.2/ui-bootstrap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.1.2/ui-bootstrap-tpls.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-controller="MainController">
<h1>Alert With Animation</h1>
<uib-alert
ng-repeat="alert in alerts"
type="{{alert.type}}"
dismiss-on-timeout="5000"
close="alerts.splice($index, 1);">{{alert.msg}}
</uib-alert>
<input type='text' ng-model='msg' />
<button ng-click="addAlert(msg,'danger')">Add Alert</button>
</body>
</html>
SCRIPT
(function() {
var app = angular.module("myApp", ['ui.bootstrap', 'ngAnimate']);
app.controller("MainController", function($scope) {
$scope.alerts = [];
$scope.msg = "No Animation!";
$scope.addAlert = function(msg, type) {
$scope.alerts.push({
msg: msg,
type: type
});
};
});
}());

Answer is based on Pankaj's comment.
Which lead me to this article: http://www.yearofmoo.com/2013/08/remastered-animation-in-angularjs-1-2.html
added class='repeat-item' to <uib-alert>..</uib-alert> element.
added proper stylings for animation effects.
<style type="text/css">
.repeat-item.ng-enter,
.repeat-item.ng-leave {
-webkit-transition: 0.5s linear all;
transition: 0.5s linear all;
}
.repeat-item.ng-enter,
.repeat-item.ng-leave.ng-leave-active {
opacity: 0;
}
.repeat-item.ng-leave,
.repeat-item.ng-enter.ng-enter-active {
opacity: 1;
}
</style>
See working demo: https://plnkr.co/edit/CK2lV4mBVGs8q5gyYklE?p=preview
One little glitch
When you click to add an alert for the very first time, there is no fade-in animation. After that, everything seems OK.

Related

Kendo dropdownlist not executing ng-focus binded function

I have this dropdown defined on template
<select id="{{vm.field.id}}"
        kendo-drop-down-list
        k-data-source="vm.field.options"
        k-data-value-field="'code'"
        k-data-text-field="'description'"
        k-index="vm.selectedIndex"
        k-ng-model="vm.field.value"
        k-value-primitive="true"
        k-options="vm.field.config"
        ng-blur="vm.unfocusField()"
        ng-focus="vm.focusField()"
        k-on-change="vm.onValueChange()">
</select>
As you can see, I have ng-focus set (targeting to vm.focusField() function), this event is rightly applied and function triggered when I focus field by clicking directly on it with the mouse. But when this field is focused by tabbing (tab keyboard) from a previous field on form list. When I press tab, the field gets "focused" since in html the class 'k-state-focused' is added to element and I can use the up and down cursor buttons to change dropdownlist value, BUT, the ng-focus binded function is not executed. In resume this ng-focus words focusing by click, but not executed focusing by tab keyboard. I proved this function is not being called in this situation using developer tools and breakpoints on binded function
I received this code sample from the telerik support team, which helped solve my problem.
<!DOCTYPE html>
<html>
<head>
<base href="http://demos.telerik.com/kendo-ui/dropdownlist/angular">
<style>html { font-size: 14px; font-family: Arial, Helvetica, sans-serif; }</style>
<title></title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.1.118/styles/kendo.common.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.1.118/styles/kendo.blueopal.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2017.1.118/styles/kendo.blueopal.mobile.min.css" />
<script src="https://kendo.cdn.telerik.com/2017.1.118/js/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2017.1.118/js/angular.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2017.1.118/js/kendo.all.min.js"></script>
</head>
<body>
<div id="example" ng-app="KendoDemos">
<div class="demo-section k-content" ng-controller="MyCtrl">
<h4>Static data</h4>
<select kendo-drop-down-list="mydropdown">
<option>Albania</option>
<option>Andorra</option>
<option>Armenia</option>
<option>Austria</option>
</select>
</div>
</div>
<script>
var app = angular.module("KendoDemos", [ "kendo.directives" ])
.controller("MyCtrl", function($scope){
$scope.$on("kendoWidgetCreated", function(event, widget){
if (widget === $scope.mydropdown) {
widget.wrapper.on("focus", $scope.onFocus);
widget.wrapper.on("blur", $scope.onBlur);
}
});
$scope.onFocus = function(){
console.log("Kendo DropDownList focused!");
};
$scope.onBlur = function(){
console.log("Kendo DropDownList blured!");
};
});
</script>

Angular materials : Basic Usage template

I would very much like to integrate in my angular app the Basic Usage template
from Angular Materials.
I really like the transition effect when the <> is clicked.
I already did a search for that directive on their website but did not find it. The closest thing I managed to find is the Toolbar, but it's slightly different in the way that the upper corners are not rounded. Also, using a simple ng-show, will not provided that transition.
Any suggestions on how to achieve this?
You can do that with angular animations which is just some simple CSS with transitions. And you are on the right track with md-toolbar. The demos use it, you just need to set some CSS to round the top corners.
md-card md-toolbar {
border-radius: 3px 3px 0 0;
}
Now add some content below the md-toolbar that you want to toggle and use ng-show on it.
<div class="toggle-content" ng-show="open">
The toggled content!
</div>
Then just check the ngShow documentation on how to animate it with CSS. What you want to animate here is the height of the toogle-content element. When it is hidden, height: 0 is applied, otherwise height: 200px.
.toggle-content {
height: 200px;
background: red;
}
.toggle-content.ng-hide-add, .toggle-content.ng-hide-remove {
transition: height linear 0.5s;
}
.toggle-content.ng-hide {
height: 0;
}
And of course you need a md-button in the toolbar that toggles the content.
<md-button ng-click="open = !open">
Toggle
</md-button>
Complete example: http://codepen.io/kuhnroyal/pen/XXZPrE
You need to implement something akin to the slideToggle() method in jquery. The Angular Slideables directive provides this functionality.
The straight corners are a custom style implemented in addition to the md-toolbar directive.
It turns out this is the closest thing that I managed to find that suits my needs.
'use strict';
angular.module('ui', ['ui.bootstrap']);
(function() {
angular.module('ui', [
"ui.bootstrap",
"ngAnimate"
]);
var module = angular.module("ui");
module.controller("controller", function($scope) {
var model = this;
model.oneAtATime = true;
model.Operators = [{
ReportItemName: "asd"
}, {
ReportItemName: "fds"
}];
});
}());
<!DOCTYPE html>
<html ng-app="ui">
<head>
<link data-require="bootstrap-css#3.1.1" data-semver="3.1.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
<script data-require="angular.js#1.4.8" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular.js"></script>
<script data-require="angular-animate#1.4.8" data-semver="1.4.8" src="https://code.angularjs.org/1.4.8/angular-animate.js"></script>
<script data-require="jquery#*" data-semver="2.1.4" src="https://code.jquery.com/jquery-2.1.4.js"></script>
<script data-require="bootstrap#3.1.1" data-semver="3.1.1" src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script data-require="ui-bootstrap#0.14.3" data-semver="0.14.3" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.14.3/ui-bootstrap.js"></script>
<script data-require="ui-bootstrap-tpls-0.11.2.min.js#0.14.3" data-semver="0.14.3" src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.14.3/ui-bootstrap-tpls.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<div ng-controller="controller as model">
<uib-accordion close-others="model.oneAtATime">
<uib-accordion-group heading="Custom template">
<uib-accordion-heading>
I can have markup, too! <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"></i>
</uib-accordion-heading>
<h1>Some Content</h1>
</uib-accordion-group>
</uib-accordion>
</div>
</body>
</html>
Other solutions that provide out-of-the-box functionality are very much welcomed.

How to change class of parent element from focus/blur?

I'm trying to add a class to the parent of an input when it gets focus. I can get the parent, but I can't seem to set the classname. Here's what I tried in this plunkr:
http://plnkr.co/edit/eEfSeDb7i3uujjBZt21z?p=preview
<!DOCTYPE HTML>
<html id="ng-app" ng-app="app"> <!-- id="ng-app" IE<8 -->
<head>
<link rel="stylesheet" href="http://nervgh.github.io/css/animate.min.css" />
<style>
.highlight {
border: 2px solid red;
}
.blue-border
{
border:2px solid blue;
}
</style>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular.min.js"></script>
<script>
angular.module( 'app', [])
.run( function( $rootScope, $timeout ) {
$rootScope.focusInput= function($event )
{
angular.element($event.target).parent().className += " " + 'highlight';
console.log( angular.element($event.target).parent() );
};
$rootScope.blurInput= function($event )
{
angular.element($event.target).parent().className.replace(' highlight', '');
};
});
</script>
</head>
<body>
<div class="blue-border">
<input ng-focus="focusInput($event)" ng-blur="blurInput($event)" value="Lactobacillus acidophilus"/>
</div>
</body>
</html>
Notice how it logs the parent successfully. However, the border does not turn red! Is there some other more "Angulary" way of doing this?
Angular's JQLite provides the 'addClass' and 'removeClass' functions for this:
angular.element($event.target).parent().addClass('highlight');
See the documentation here: https://docs.angularjs.org/api/ng/function/angular.element

Broken bindings when using modal dialog in angular

I am using the ngModal modal dialog box directive for my angular application. It's displaying some weird behavior that I don't quite understand. When I attach variables directly to the controller's $scope and reference them in the dialog box, the binding breaks. Changing their values in the dialog has no effect on the variables in the controller. But if I add the variables as properties to an object and then add the object to the $scope it works. In other words, if I do this
$scope.v1 = 1
$scope.v2 = 'abc'
it doesn't work, but if I do
$scope.myData = {
v1: 1,
v2: 'abc'
}
things work fine. What's the deal? You can see a working version of the code here and a broken version here.
If the plunk apps aren't loading for you, here is the code:
html
<!DOCTYPE html>
<html data-ng-app='ngModalDemo'>
<head>
<title>ngQuickDate Demo</title>
<link href="http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="ng-modal.css" media="all" />
<style type='text/css'>
body{font-family:'Helvetica Neue',Helvetica,sans-serif}
h1 { padding: 0; margin: 0; }
.ng-cloak { display: none; }
</style>
</head>
<body>
<div ng-controller='DemoController'>
<modal-dialog show='myData.modalShown' width='500px' dialog-title='Modal Dialog Title' on-close='logClose()'>
<p>This is some html content</p>
<p>
<label for='hello'>Hello:</label>
<input type='text' name='hello' ng-model='myData.hello' />
</p>
<p>
<label for='foo'>Foo:</label>
<input type='text' name='foo' ng-model='myData.foo' />
</p>
<img src='http://upload.wikimedia.org/wikipedia/commons/2/22/Turkish_Van_Cat.jpg' width='300px'/>
</modal-dialog>
<button ng-click='toggleModal()'>Toggle Modal</button>
<br/>
<br/>
<br/>
<p><strong>Shown?</strong> {{myData.modalShown}}</p>
<p><strong>Hello</strong>: {{myData.hello}}</p>
<p><strong>Foo</strong>: {{myData.foo}}</p>
</div>
<script type="text/javascript" src="https://code.angularjs.org/1.3.0-beta.5/angular.js"></script>
<script type="text/javascript" src="ng-modal.js"></script>
<script type="text/javascript" src="app.js"></script>
<script type="text/javascript" src="controller.js"></script>
</body>
</html>
angular app
app.config(function(ngModalDefaultsProvider) {
return ngModalDefaultsProvider.set({
closeButtonHtml: "<i class='fa fa-times'></i>"
});
});
angular controller
app = angular.module('ngModalDemo')
app.controller('DemoController', function($scope) {
$scope.myData = {
link: "http://google.com",
modalShown: false,
hello: 'world',
foo: 'bar'
}
$scope.logClose = function() {
console.log('close!');
};
$scope.toggleModal = function() {
$scope.myData.modalShown = !$scope.myData.modalShown;
};
});

Page Transition with AngularJS and CSS Animations

I'm working on a basic AngularJS app. This app will have pages that are going to be defined within templates. When a user changes pages, I want to be able to show the other page with a basic animation. Currently, my app is doing this. However, the previous page drops below the new page and sort of flickers. I can't figure out why this is happening. Here is my code:
<!doctype html>
<html lang="en" ng-app="app">
<head>
<meta charset="utf-8">
<title>My HTML File</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular-route.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0rc1/angular-animate.js"></script>
<style type="text/css">
.myAnimation { height:480px; width:640px; overflow:hidden; }
.myAnimation.ng-enter { animation-duration: .3s; animation-name: fadeIn; animation-timing-function: cubic-bezier(.71,.55,.62,1.57); }
.myAnimation.ng-leave { animation-duration: .3s; animation-name: fadeOut; animation-timing-function: cubic-bezier(.71,.55,.62,1.57); }
#keyframes fadeIn {
from { opacity: 0; transform: scale(.9, .9); }
to { opacity: 1; transform: scale(1, 1); }
}
#keyframes fadeOut {
from { opacity: 1; }
to { opacity: 0; }
}
</style>
</head>
<body style="margin:0; padding:0;">
<ul style="list-style-type:none; margin:0px; padding:0px;">
<li style="display:inline;"><a href='#page1'>Page 1</a> </li>
<li style="display:inline;"><a href='#page2'>Page 2</a> </li>
</ul>
<div style="display:block; border:1px solid black;">
<div ng-view class="myAnimation"></div>
</div>
<script type="text/javascript">
angular.module('app', ['ngRoute', 'ngAnimate']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/page1', {templateUrl: 'views/page1.html', controller: Page1Ctrl}).
when('/page2', {templateUrl: 'views/page2.html', controller: Page2Ctrl}).
otherwise({redirectTo: '/page1'});
}]);
function Page1Ctrl($scope, $http) {
}
function Page2Ctrl($scope, $http) {
}
</script>
</body>
</html>
How do I prevent the scrollbar from appearing when I change pages? And prevent the older page from dropping below the new page?
Thank you!
It's likely that you need to give the animated divs a position:absolute; style during the animations.
What is happening is that the second template is being loaded into the DOM while the first template is still doing the fade-out animation. Without position:absolute they do what is natural and start block stacking until the first template has fully faded out and Angular removes it.
Keep in mind if you add position:absolute you may also have to play with the "Top" value to position it correctly depending on which parent element has position:relative or absolute.
You can put the position:absolute class on the animated div generally, or just specifically on the animating classes depending on what works better for your app structure.

Resources