Angular ng-show with fade expression does not remove the div - javascript

I am trying to display a div with an error message with ng-show along with ng-class set as fade with an expression. The message fades away after the set time, however, the div created to display the error message does not get removed.
I would like the created div to be removed as well when the message fades. Could someone please help?
Here is my codepen - link
Here is my code for the html
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap.min.css" rel="stylesheet"
type="text/css" />
<section data-ng-app="app" class="container" data-ng-controller="messageController">
<hr />
<div data-ng-show="showError" ng-class="{fade:doFade}" class="alert alert-danger"><strong>Error:</strong> {{errorMessage}}</div>
<button data-ng-click="fakeError()" class="btn btn-default">Fake an Error</button>
<hr />
</section>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
and the JS code
var app = angular.module('app',[]);
app.controller('messageController', ['$scope', '$timeout', function($scope, $timeout){
$scope.showError = false;
$scope.doFade = false;
$scope.fakeError = function(){
//reset
$scope.showError = false;
$scope.doFade = false;
$scope.showError = true;
$scope.errorMessage = 'We\'re mixing apples and oranges!';
$timeout(function(){
$scope.doFade = true;
}, 2500);
};
}]);

ng-show sets only style display conditionaly, soyour div will be always present in the page, only not visible if condition is falsy.
Use ng-if instead to conditionaly add/remove element.
Easiest way to animate ng-if is to use angular-animate library. Using this lib you will get control over rendering stages of various directives.
These stages are marked via specific css classes, which you can target and style
transitions of element.
For ng-if directive, there are available classes .ng-enter, .ng-leave, .ng-enter-active, .ng-leave-active
Via these classes you can define desired transition, in your case it is fade.
Example of fading on remove:
https://codepen.io/anon/pen/NzyqvL

Related

Change style of multiple element groups simultaneously on hover using Angular

I find myself needing to change style of all elements that have an attribute in common (let's say a class name) when one of these elements is hovered. This is super easy to do with jQuery, like this:
$(function() {
$('.bookId4').hover( function(){
$(this).css('background-color', '#F00');
},
function(){
$(this).css('background-color', '#000');
});
});
Though I don't know how to achieve this with Angular. In this example, the elements that have the class .bookId4 are generated with Angular AJAX call, so I'd like to use Angular to create the hover effect as well. Thank you!
EDIT
To explain further, I will have many divs being generated with an AJAX call, and the div's that are in the same group will have the same class. This is the HTML code:
<div class="bookId{{ privateTour.booking.id }}"> <!-- Wrapper for hover effect -->
When one of the divs is hovered I want ALL of the divs (not only the div that is being hovered) with the same class (or some other value that they may have in common) to have a hover effect. My preferred way would be for Angular to search the whole page for all divs with a certain class name and apply a style to that class (to not have to for example generate tons of CSS for all the classes that were generated, which I'm not even sure it would work).
You can do that by using ng-mouseenter and ng-mouseleave directives, Here is the simple code, you can build on top of it to meet your requirements
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example - example-example73-production</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
</head>
<body ng-app="">
<h1 ng-style="myStyle" ng-mouseenter="myStyle={'background-color':'blue'}"" ng-mouseleave="myStyle={'background-color':'none'}"">Hello World</h1>
</body>
</html>
You can apply simple css solution for hover, like
.bookId4:hover {
background-color: '#F00';
}
No need for angular or jQuery :-)
Yes I agree with using ng-mouseenter and ng-mouseleave.
I did a example hope can help you
https://embed.plnkr.co/Cxfv0I9IEfBhZYj8A3zS/
use ng-class, create one scope variable which is by default false.
when mouseEnter OR mouseLeave event occurs make it TRUE/False accordingly.
<style>
.bookId4{color: red;}
</style>
<span ng-mouseenter="ctrl.hovered()" ng-mouseout="ctrl.nothovered()" ng-class="{ 'bookId4' : ctrl.ishovered==true }">soemthing 1</span>
<span ng-mouseenter="ctrl.hovered()" ng-mouseout="ctrl.nothovered()" ng-class="{ 'bookId4' : ctrl.ishovered==true }">soemthing 2</span>
<span ng-mouseenter="ctrl.hovered()" ng-mouseout="ctrl.nothovered()" ng-class="{ 'bookId4' : ctrl.ishovered==true }">soemthing 3</span>
_this.ishovered =false;
_this.hovered = function(){
_this.ishovered =true;
}
_this.nothovered = function(){
_this.ishovered =false;
}
In the end I found using an ng-class condition to be the best solution, and a variable decides what group should be highlighted. This line that I initially tried using did not work correctly:
<div ng-class="hovering == privateTour.booking.id ? 'hl' : ''" ng-mouseenter="hovering = privateTour.booking.id" ng-mouseleave="hovering = 0"> <!-- Wrapper for hover effect -->
For some reason, only the hovered div was highlighted, so I had to send the signal to a variable using a function instead for it to have a global effect. I ended up using this code for the div wrappers:
<div ng-class="hovering == privateTour.booking.id ? 'hl' : ''" ng-mouseenter="setHover(privateTour.booking.id)" ng-mouseleave="setHover(0)"> <!-- Wrapper for hover effect -->
And I wrote this simple function in the scope:
$scope.setHover = function(bookId) {
$scope.hovering = bookId;
};
And here's the style for the highlight class .hl:
.hl {
background-color: red;
}
Thank you for everyone giving the lead of ng-mouseenter and ng-mouseleave!

Preloader with AngularJs

I have a really simple Html web site (No server side code). Instead of replicate some HTML, I decided to use angularJs. Using some directives and some partial views, I could re-use some code without replicate it.
I created a directive for preloader, but I have a problem.. The preloader is shown a bit later than the loading of the page... What I mean is that some images and text are loaded, then the preloader appear, and finally when the document is ready the preloader disappear... It's really annoying!!
I would like that the preloader appeared immediately before of everything, but perhaps in that moment angular has not been loaded yet. I don't know If I am clear.
In any case, here you can see what I mean:
the example
Here my code:
HTML PAGE
<head>
...
<script src="/js/angularjs-1.4.8.min.js"></script>
<script src="/js/angularjs/app.js"></script>
<script src="/js/angularjs/directives/preloader.js"></script>
</head>
<body ng-app="renovahaus">
<rh-preloader></rh-preloader>
...
</body>
JS - DIRECTIVE
angular.module('renovahaus')
.directive('rhPreloader', ['$document', function ($document) {
return {
restrict: 'E',
replace: true,
templateUrl: '/partial_views/directives/templates/preloader.html',
link: function (scope, element, attr) {
$document.ready(function () {
/*will first fade out the loading animation*/
$(element).find("#status").fadeOut();
/*will fade out the whole DIV that covers the website.*/
$(element).delay(1000).fadeOut("slow");
$("body").css('overflow-y', 'visible');
$("body").css('position', 'relative');
});
}
};
}]);
HTML - TEMPLATE DIRECTIVE
<div class="preloader">
<div id="status"></div>
<div id="loading-center">
<div id="loading-center-absolute">
<div class="object" id="object_four"></div>
<div class="object" id="object_three"></div>
<div class="object" id="object_two"></div>
<div class="object" id="object_one"></div>
</div>
</div>
</div>
thank you
Some possibilities to try :
Add the class ng-cloak to your <div id="wrapper">
Put your whole Page (except the preloader) in a ng-include ? All the dom from the div with id "wrapper".
Otherwise you could use the route module of angular which will contains a template where all your content will be.
I have modified the div with id "wrapper" in order to be hidden (visibility: hidden) and in orderd to be shown when the preloader disapper. Surely not the correct way to approach, but solved my problem.

Dynamic show hide code for dynamic content angular js

Run below code as it is, Code is working fine but i want the same functionality without polluting angularjs code.
<html>
<head>
<title></title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
</head>
<body ng-app="newapp" ng-controller="newctrl">
<div ng-repeat="x in names">
<div data-ng-click="toggleCompanyArr(['nav_' + x.id])">This is id : {{x.id}}</div>
<div id="nav_{{x.id}}" style="display:none">{{x.firstname}} {{x.lastname}}</div><br><Br><Br>
</div>
</body>
<script>
var app = angular.module('newapp',[]);
app.controller('newctrl', function($scope){
$scope.names=[
{"id":"1","firstname":"Akhilesh","lastname":"Kumar"},
{"id":"2","firstname":"Aman","lastname":"Kumar"},
{"id":"3","firstname":"Mithilesh","lastname":"Kumar"}
];
$scope.toggleCompanyArr = function(val){
$("#"+val).toggle();
};
});
</script>
</html>
You don't need to use jQuery to show/hide div, you could simply use ng-show here.
For achieving this you need to add show flag on each element of the names collection (you don't necessary to add new show property to your collection, if you don't add show: false prop in your each names element, angular will take care of this), and toggle show flag on click of the element. Thereafter use x.show flag inside ng-show directive to show & hide div.
Basically on initial load x.show value either undefined or false so anyhow it is going to hide the all element content on load. When you click on element ng-click directive will flag to x.show = true and that element will get shown.
The other advantage behind this approach is, you could have state of your each element in its object.
Suppose you have akhilesh option selected then it will have {"id":"1","firstname":"Akhilesh","lastname":"Kumar", show: true}, & other will have show: false if those element are not clicked.
Markup
<div data-ng-click="x.show = !x.show">
This is id : {{x.id}}
</div>
<div ng-show="x.show">
{{x.firstname}} {{x.lastname}}
</div>
Reference link

Priority element in directive

I have two element in the same page:
one is into a div and another one is into an overlay.
I want to display only the element inside the overlay and not element in the page (it is also hide by overlay).
I don't know how can I prevent this... I bind the directive by attributes, maybe should I pass some other params to element?
This is plunker example: Plunker
As you can see, I want to hide text in page when modal (simple example, but I use another plugin) is open and show it in modal and viceversa... I preferer to use only directive and/or some more attributes in the element...
I test a lot but I don't find solution...
Code:
angular...[]....directive('example', function() {
return {
restrict: 'A',
replace: true,
link: function($scope, $element, $attrs) {
$scope.display = "IT's WORK TEXT BY DIRECTIVE";
}
};
});
<script type="text/ng-template" id="myModalContent.html">
<!--Modal-->
<div class="modal-body">
<span example="" class="text-danger"><br><br>{{display}}<br><br></span>
</div>
</script>
<button type="button" class="btn btn-default" ng-click="open()">Open me!</button>
<span example="" class="text-danger"><br><br>{{display}}<br><br></span>
You can use a combination of ng-show and a js closure passed to the modal for toggling the visibility of your text. So... the display visibility will be controlled by the ng-show
<span example="" ng-show="elemVisibility" class="text-danger"><br><br>{{display}}<br><br></span>
You can toggle the visibility with a js helper function
function _setElemVisiblity (isModalOpen) {
$scope.elemVisibility = !isModalOpen;
}
You can pass this as a callback to your modal and trigger it whenever you open/close the modal.
Updated plunk here

Ajax spinners for angularJS

I am trying to show ajax spinners on one of angularJS application with every http call, so it means whenever we try to load a ngGrid or Dropdown etc there will be a spinner on place and when loading get complete it will get removed, I am new on angular not sure how can we achieve it, please give any reference.
Thanks
Try using an ngSwitch, where you will swap two templates, so basically it would be something like this:
<div ng-switch on="loaded">
<div ng-switch-when="true">
<!--your loaded content goes here-->
</div>
<div ng-switch-default>
<!--your spinner goes here-->
</div>
</div>
That way in your controller you can do something like:
$scope.loadSomething = function(){
$scope.loaded = false;
$http.get(url).success(function(data){
$scope.loaded = true;
});
};
You could write some plain old JavaScript to add a class name to the DIV or TABLE before the call to $http.foo, and then in a success/failure callback remove that class name.
CSS:
.loading {
background: transparent url(path/to/loading.gif) no-repeat scroll 50% 50%;
}
.loading * {
visibility: hidden;
}

Categories

Resources