Adding sliding transition to ng-repeat div - css

Our team has created a widget in ServiceNow that shows a row of icons and show/hide additional details in a div when icons are clicked. This is what our html and client controller looks like:
<div class="icons">
<ul class="flex justify-content-center align-items-center">
<li ng-repeat="item in c.data.linksArray track by $index">
<a class="link" href="javascript:void(0)" ng-click="c.getInfo(item)">
<i title="{{item.titles}}" class='fa {{item.icon}} fa-3x circle-icon'></i>
</a>
</li>
</ul>
</div>
<div class="linkList text-center"
ng-repeat="thing in c.data.linksArray track by $index"
ng-if="thing.isVisible==true">
<ul>
<li class="m-b-sm" ng-repeat="link in thing.links">
{{link.link_title}}
</li>
</ul>
</div>
function($scope) {
/* widget controller */
var c = this;
c.getInfo = function(item) {
var isDisplaying = false;
if(item.isVisible== true){
isDisplaying = true;
}
for(var i=0; i<c.data.linksArray.length; i++){
c.data.linksArray[i].isVisible = false;
}
if(isDisplaying == true){
item.isVisible = false;
}else{
item.isVisible=!item.isVisible;
}
}
console.log('icon-link-list');
console.log($scope);
}
This all works fine, but we'd like to refine it by adding a sliding effect to the .linkList class. Right now, when an icon is clicked, the .linkList div appears very abruptly. Is there a way to add a sliding transition effect to that div using css?

You can solve this by pure css animations. Aplly this css to the item which will we hidden/shown. The animation will play anytime css attribute 'display' will change. I guess it's the linkList element?
.linkList {
animation: slideFromLeft .2s;
animation-timing-function: ease;
animation-fill-mode: forwards;
opacity: 0;
}
#keyframes slideFromLeft{
0% {
opacity: 0;
transform: translateX(50px);
}
100% {
opacity: 1;
transform: none;
}
}
Edit: you maybe have to change ng-if on linkList to ng-show.

From the Docs:
Animations in AngularJS are completely based on CSS classes. As long as you have a CSS class attached to an HTML element within your application, you can apply animations to it.
As ngRepeat does its thing, each time a new item is added into the list, ngRepeat will add an ng-enter class to the element that is being added. When removed it will apply an ng-leave class and when moved around it will apply an ng-move class.
For more information, see
AngularJS Developer Guide - Animations

Related

HTMX - Transition on target element

I've been experimenting with HTMX recently and I cant seem to find a way to apply a transition to a target element. I have a form that submits a GET request and returns a table.
<form class="mt-3" hx-get="/data/statement/AJAX" hx-target="#statementAJAX" >
It basically returns a div containing the table like this:
<div id="statementAJAX" class="fade-in">
</div>
the CSS for the div is the following:
.fade-in {
opacity: 1;
animation-name: fadeInOpacity;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 0.5s;
}
#keyframes fadeInOpacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
Now the css transition works when i first load the page but when I execute the AJAX request nothing happens.
I tried apllying style="opacity:0" to the form but obviously it applies only to the form and not the target...
Any idea how to apply the transition to the target element?
What you have there works for me. Are you trying to replace the entire table or add to the table?
This works for me using your CSS and hx-swap="outerHTML" to replace the table.
<a href="#" id="test" hx-get="/load.html" hx-target="#table" hx-trigger="click" hx-swap="outerHTML">
Submit
</a>
<div id="table" class="fade-in"></div>
load.html
<div id="table" class="fade-in">
table content
</div>

How do you apply css to the parent's sibling element when input is checked?

I'm working on getting a mobile hamburger navigation to work, but I'm having trouble applying CSS to the element due to nesting/relation of the elements. I have the hamburger icon (#mobile-menu) animating properly based on the input (#nav-trigger) being checked or not (turns into an X).
But when #nav-trigger is checked, i also want to change the absolute positioning of #header-nav (bringing it into view when checked). This is where I'm stuck. How do i use CSS selectors to apply a CSS rule change to #header-nav when #nav-trigger is checked? I'm using SCSS and i've tried nesting selectors like ~, +, and more but i can't get it to work. Any help is greatly appreciated. Thank you!
<nav id="header-nav">
<ul>
<li>
<a>Nav item</a>
</li>
<li>
<a>Nav item</a>
</li>
<!-- etc... -->
</ul>
</nav>
<div id="mobile-menu-container">
<div id="mobile-menu-div">
<label id="mobile-menu-label" for="nav-trigger"></label>
<input type="checkbox" id="nav-trigger"/>
<div id="mobile-menu"></div>
</div>
</div>
Use javascript - no broswer support (yet) to go "back" "Traversing" (parent - parent - sibling and so on) by CSS only.
div :parent :parent ~ .... no way!! :)
Related StackOverflow Q:
Is there a CSS parent selector?
Basic vanilla JS example:
var checkbox = document.querySelector("input[name=hamburger]");
var header = document.getElementById("header-nav");
var label = document.getElementById("mobile-menu-label");
var checked = checkbox.checked;
if (checked){
// Checkbox is checked..
header.classList.toggle('active');
label.innerHTML = "by deafult checked";
} else{
label.innerHTML = "by deafult not checked";
}
checkbox.addEventListener( 'change', function() {
if(this.checked) {
// Checkbox is checked..
header.classList.toggle('active');
label.innerHTML = "is true";
} else {
// Checkbox is not checked..
header.classList.toggle('active');
label.innerHTML = "is false";
}
});
input[type=checkbox]:checked ~ #mobile-menu {
color: white;
background-color: magenta;
transition: background-color 0.5s ease;
font-style: normal;
cursor: pointer;
}
#header-nav.active{
transition: background-color 0.5s ease;
background: red;
}
label{
cursor: pointer;
}
<nav id="header-nav">
<ul>
<li>
<a>Nav item</a>
</li>
<li>
<a>Nav item</a>
</li>
<!-- etc... -->
</ul>
</nav>
<div id="mobile-menu-container">
<div id="mobile-menu-div">
<input name="hamburger" name="nav-trigger" type="checkbox" id="nav-trigger" checked/>
<label id="mobile-menu-label" for="nav-trigger">Hello</label>
<div id="mobile-menu">hamburger</div>
</div>
</div>
by jquery
Use toggleClass() Method:
https://www.w3schools.com/jquery/html_toggleclass.asp
Related StackOverflow Q: Jquery if checkbox is checked add a class
jQuery Traversing Methods
jQuery traversing, which means "move through", are used to "find" (or
select) HTML elements based on their relation to other elements.
https://www.w3schools.com/jquery/jquery_ref_traversing.asp

Angular ng-repeat animate once

I am using ngAnimate to animate entries in an ng-repeat. When loading the data all elements are animated as I have defined in my css:
.chat-message.notice.ng-enter {
-webkit-animation: rubberBand 1s;
-moz-animation: rubberBand 1s;
-ms-animation: rubberBand 1s;
animation: rubberBand 1s;
}
This works when a notice is appended with the following html:
<ul>
<li class="media chat-message pointer fade-animate"
ng-repeat-start="message in guestbook.messages track by $index"
ng-if="!message.bot">
<!-- more html -->
</li>
<li class="chat-message notice" ng-repeat-end ng-if="message.bot">
<div>
<p class="text-center">
{{ message.message }}
<small>({{ message.date | amTimeAgo }})</small>
<span class="close pull-right" ng-click="guestbook.remove(message)">×</span>
</p>
</div>
</li>
</ul>
However, when a new message is appended (at the top), every element is again animated. Is there a way that elements animate only once? That when a new message is appended to the array, only that element will animate?
JSFIDDLE
EDIT
After a few clicks on a 'new message', I can see not all notices are animated. Maybe it has something to do with the ng-repeat-start and ng-repeat-end?
If understood correctly just change this:
$scope.messages.unshift(message);
to this:
$scope.messages.push(message);
Even above answer fixed the problem, my solution might be helpful in other scenarios. The fix is pretty straightforward.
Use Angular varible $first and just add CSS class for the first element using ng-class directive in your HTML. In this example, class "first" will be added only to first element in ng-repeat:
ng-class="{'first': $first===true}"
and then apply animation rules to element with "first" CSS class
.chat-message.notice.first.ng-enter {
color:red !important;
font-weight:bold;
animation: rubberBand 1s;
}
Updated JSFIDDLE: http://jsfiddle.net/t6x3a1zj/7/

How do I make my text disappear when I hover over my div?

This is the only thing in the body of the HTML:
<div id="box">
<p id="text"> Enter The Disco! </p>
</div>
and this is my CSS relating to the problem:
#box:hover{
-webkit-transform:rotate(360deg);
opacity:1;
background-image:url("Logo.jpg");
width:428px;
height:208px;
font-size:38px;
}
#text:hover{
padding:18% 0% 0% 0%;
color:red;
}
And what I want to do is make the text inside the div disappear when I hover over it how do I do this? It already spins and changes background but i just want the text to disappear after it has finished its animation.
You could use the color CSS attribute and instead of making it invisible, just make it transparent, which should have the same effect:
#text:hover {
/* other rules */
color: transparent;
}
you can use different way too. It is easy too like another solutions:
#text:hover {
display:none;
}
It's no problem to let it disappear: use display:none, opacity:0, visibility:hidden or color:transparent; but hiding it AFTER the animation? This seems to be a bit more difficult. I don't think that this is possible without javascript:
<div id="box" onmouseover="spin();">
<p id="text"> Enter The Disco! </p>
</div>
<script type="text/javascript">
var i; var rotate;
function spin() {
i = 180; rotate = setInterval("spinInterval()",3);
}
function spinInterval() {
document.getElementById('box').style.WebkitTransform = "rotate("+ i +"deg)";
document.getElementById('box').style.MozTransform = "rotate("+ i +"deg)";
document.getElementById('box').style.OTransform = "rotate("+ i +"deg)";
document.getElementById('box').style.Transform = "rotate("+ i +"deg)";
i++;
if(i>360) {
document.getElementById("text").style.opacity = 0;
clearInterval(rotate);
}
}
</script>
PS: this works for all browsers, not only on Chrome :)

How to animate a dropdown menu using CSS3 animations?

I would like to add a CSS3 effect to my dropdown. (Just like that one in Instagram.com on "My profile").
I'm using Animate.css for the CSS3 effects.
I tried this, but it doesn't work.
HTML
<%=fa_icon "bell"%>
<ul id="dropdownalerts" class="f-dropdown text-left animated bounceInDown" data-dropdown-content>
<li><%=link_to "Facebook", "#"%></li>
<li><%=link_to "Email", "#" %></li>
</ul>
JS
$(document).ready(function(){
$('a').hover(function(){
$("ul").addClass('animated bounceInDown');
});
});
You can find a live version on Zapping.io
I got it working in an example. I used the HTML you provided, and then downloaded the bounceInDown animation and used that for the CSS in the examples below.
jsFiddle example here - hover method
jQuery
$(document).ready(function(){
$('a').hover(function() {
$("ul").addClass('animated bounceInDown');
},function(){
$("ul").removeClass('animated bounceInDown');
});
});
If you want to add a delay when hovering off, use something like this:
jsFiddle example - hover method with delay.
$(document).ready(function(){
$('a').hover(function() {
$("ul").addClass('animated bounceInDown');
},function(){setTimeout(function(){
$("ul").removeClass('animated bounceInDown');
}, 750);});
});
Those examples are assuming you want the animation fired on hover. If you want it fired on click, use something like this instead:
jsFiddle example click method - Look below for an alternative non-JS method.
$(document).ready(function(){
$('a').click(function() {
$("ul").toggleClass('animated bounceInDown');
});
});
Alternative method - No JS/jQuery
If you don't want to use JavaScript/jQuery, you can use the checkbox hack in CSS.
This essentially toggles between :checked, thus activating the animation.
jsFiddle example - It works in all current browsers.
HTML
<label id="click" for="dropdown">Click here</label>
<input style="display:none" type="checkbox" id="dropdown">
<ul id="dropdownalerts" class="f-dropdown text-left" data-dropdown-content>
<li>Facebook</li>
<li>Email</li>
</ul>
CSS - (only part of it) See the example above for full CSS.
input[type=checkbox]:checked ~ #dropdownalerts {
display:inline-block;
-webkit-animation: bounceInDown 1s both;
-moz-animation: bounceInDown 1s both;
-o-animation: bounceInDown 1s both;
animation: bounceInDown 1s both;
}

Resources